无法弄清楚如何使用MongoDB的$ bitsAnySet运算符

时间:2019-11-22 22:52:06

标签: javascript mongodb bitmask

每次我被一些小项目困扰时,Stackoverflow总是对我有帮助,但是我从来没有真正问过自己一个问题。这次我还是找不到我的问题。

我正在做一个小项目,需要在我的MongoDB数据库中存储工作时间。我决定在整个星期内使用由336位表示的位掩码,这意味着每一位代表一天中的30分钟。 (使用位掩码没有特殊原因。我愿意更改存储工作时间的方式,但无论如何我都很好奇。)

我认为,如果我使用$ bitsAnySet运算符基于位掩码进行查询,将会很方便,因为我可以弄清楚如果客户在下午4点查询开放业务时需要设置的位置。

在阅读有关运算符(https://docs.mongodb.com/manual/reference/operator/query/bitsAnySet/)的文档时,我发现您可以提供一系列要检查的职位,这非常适合我的需求。

但这是要抓住的地方。我不知道这些职位是如何工作的。 docs指出,位置0将位于最低有效位(最右边),这意味着如果查询$ bitsAnySet:[0],则找不到以营业时间存储的数字254(0b1111 1110)的文档,因为在此示例中,最右边的位设置为0。

以这种方式使用操作员,对我的测试数据进行测试,因为定位似乎不匹配,我总是遇到问题。

因此,我为自己编写了一个小脚本(在使用Mongoose连接到MongoDB的NodeJS v12上运行的JavaScript中),该脚本只是尝试所有可能的位置:

这是我的脚本:

require ('mongoose').connect ('mongodb://localhost/test', {useCreateIndex: true, useNewUrlParser: true, useFindAndModify: false, useUnifiedTopology: true}).then (() => {

    let buffer = Buffer.alloc (6, 0);

    // 0xC0 => 0b1100 0000
    buffer.writeUInt8 (0xC0, 0);
    // 0x07 => 0b0000 0111
    buffer.writeUInt8 (0x07, 5);

    // buffer should be: 11000000 00000000 00000000 00000000 00000000 00000111

    new SomeModel ({data: buffer}).save ().then (model => {

        let promises = [];

        // just trying out each position
        for (let index = 0; index < 48; index ++)
            promises.push (SomeModel.findOne ({data: {$bitsAnySet: [index]}}))

        Promise.all (promises).then (resolved => {

            resolved = resolved.map ((item, index) => {
                if (item !== null)
                    return {index, item: item.data.toString ('hex')};
                else return null;
            });

            // yes, I know it's not very performant to go over the entire array a second time,
            // because I could have done it in the first round, 
            // but this was just some quick and dirty testing :D
            resolved = resolved.filter (item => item !== null);
            console.log (resolved);

        }) 

    }).catch (console.log);

}).catch (console.log);

这是我的小测试脚本,我期望输出如下:

[
 {index: 0, item: 'c00000000007'},
 {index: 1, item: 'c00000000007'},
 {index: 2, item: 'c00000000007'},

 {index: 41, item: 'c00000000007'},
 {index: 42, item: 'c00000000007'},
]

因为查看从右边来的二进制表示形式,它应该首先在位置0、1和2处找到三个,然后在最左端找到最后两个。

但是我明白了:

[
  { index: 6, item: 'c00000000007' },
  { index: 7, item: 'c00000000007' },

  { index: 40, item: 'c00000000007' },
  { index: 41, item: 'c00000000007' },
  { index: 42, item: 'c00000000007' }
]

这让我大吃一惊,因为这对我来说是完全出乎意料的,因为它突然看起来像是MongoDB从左开始,因为它在三者之前找到了两个,而这两个都位于最左边二进制数据。这也让我感到困惑的是,它似乎不是从位置0开始的。

如果我没记错的话,我的数据以两个1开始,以3结尾。因此,$ bitsAnySet:[0]应该是正确的。

你们当中有人知道我在做什么错吗? 非常感谢您的帮助!

注意:如果我错了,请纠正我,但我相信Promise.all不会改变数组的顺序,这意味着它不能只是一个承诺在解决之前另一个更改其在“承诺”数组中的位置。

注意:该模型没有任何其他字段。它只有默认的_id字段和data字段。

0 个答案:

没有答案
相关问题