数组 – 如何在子文档的每个字段中搜索

这是我的文件:

{ "_id" : ObjectId("5259b73b4949e0b22608960d"), "array" : [  "a",  "b" ] }

要在数组字段中查找某些值,请使用以下查询:

db.collection.find({roles: 'a'})

但是我遇到了这个问题,当数组字段看起来像这样:

{ "array": { '0': 'a', '1' : 'b' } }

如何使用这种类型的数组(实际上是所有字段都是数组索引的子文档),我怎么能像以前一样进行相同的查询?
所以我需要找到一个文档,其中任何子文档的字段等于某个东西.

不幸的是,我无法更改此字段,因为它是由第三方API生成的.

最佳答案 我没有看到比使用
the $where operator更好的选择,它允许您通过指定自定义JavaScript函数来过滤集合.

请注意,对于大型集合,这可能会造成性能问题,因为$条件无法利用索引.

好的,回到问题:在{“数组”:{‘0’:’a’,’1’:’b’}}文字中,数组在技术上不是数组,而是属性为’0’的对象,’1’和’2′.

假设所有数组对象都有一个从’0’开始的连续属性列表,你可以迭代直到你找到匹配,或者数字i为哪个数组[i]是未定义的(表示连续属性序列的结束) .

实现此目的的JavaScript函数是:

function () {
    for(var i = 0; this.array[i] !== undefined; i++) {
        if(this.array[i] === 'b') {
            return true;
        }
    } 

    return false; 
}

要轻松将其粘贴到Mongo shell中,这是单行版本:

function () {for(var i=0; this.array[i]!==undefined; i++) {if(this.array[i]==='b') {return true; } } return false; }

请注意有关上述脚本的两件事:

>如果属性的名称不同于“array”,则应更改this.array
>’b’是要在“数组”中搜索的值.将此更改为您正在搜索的任何内容.

因此,使用上面的脚本,这是您可以在Mongo shell中编写的内容:

db.arraycollection.find({$where: function() {for(var i=0; this.array[i]!==undefined; i++) {if(this.array[i]==='b') {return true; } } return false; }});

为了简化一些事情,因为这是find()的唯一条件,我们可以省略$where,只留下js函数作为参数:

db.arraycollection.find(function() {for(var i=0; this.array[i]!==undefined; i++) {if(this.array[i]==='b') {return true; } } return false; });

PS:对不起上面的长行让你滚动,但我认为单行更方便粘贴在Mongo shell中.

点赞