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

时间:2013-10-12 21:12:24

标签: arrays mongodb mongodb-query

这是我的文件:

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

要在array字段中找到一些值,请使用以下查询:

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

但是我遇到了问题,array字段看起来像这样:

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

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

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

2 个答案:

答案 0 :(得分:2)

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

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

好的,回到问题:在{ "array": { '0': 'a', '1' : 'b' } }字面值中,array在技术上不是数组,而是具有属性'0''1'和{的对象{1}}。

假设所有'2'个对象都有一个从array开始的连续属性列表,您可以迭代直到找到匹配项,或者'0'iarray[i](表示连续属性序列的结束)。

实现此目的的JavaScript函数是:

undefined

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

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

    return false; 
}

注意上面脚本的两件事:

    如果属性的名称不同于function () {for(var i=0; this.array[i]!==undefined; i++) {if(this.array[i]==='b') {return true; } } return false; } ,则应更改
  • this.array
  • "array"是要在“数组”中搜索的值。将此更改为您正在搜索的内容。

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

'b'

为了简化一点,因为这是db.arraycollection.find({$where: function() {for(var i=0; this.array[i]!==undefined; i++) {if(this.array[i]==='b') {return true; } } return false; }}); 的唯一条件,我们可以完全省略find(),只留下js函数作为参数:

$where

PS:很抱歉上面的长行会让你滚动,但我认为单行可以更方便地粘贴到Mongo shell中。

答案 1 :(得分:0)

您可以使用$elemMatch找到数组的子文档:

db.collection.find( { "_id" : ObjectId("5259b73b4949e0b22608960d") },
             { array: { $elemMatch: { 0: '1'} } )

这会从你的集合中找到具有特定对象id的'array',以及匹配{0:'1'}对象的数组的对象。