每次我被一些小项目困扰时,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字段。