【问题标题】:How to search in every field of subdocument如何在子文档的每个字段中进行搜索
【发布时间】:2013-10-20 18:43:08
【问题描述】:

这是我的文件:

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

要在 array 字段中查找某些值,我使用以下查询:

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

但我遇到了问题,array 字段如下所示:

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

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

很遗憾,我无法更改此字段,因为它是由第 3 方 API 生成的。

【问题讨论】:

    标签: arrays mongodb mongodb-query


    【解决方案1】:

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

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

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

    假设所有array 对象将具有从'0' 开始的连续属性列表,您可以迭代直到找到匹配项或i 的数字array[i]undefined(表示连续属性序列的结束)。

    实现这一点的 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' 是要在 "array" 中搜索的值。将其更改为您要搜索的任何内容。

    因此,使用上面的脚本,您可以在 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 中。

    【讨论】:

    • 感谢您的回答!我很快就会尝试。
    【解决方案2】:

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

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

    这将从您的集合中找到具有特定对象 ID 的“数组”,以及与 {0: '1'} 对象匹配的数组对象。

    【讨论】:

    • 这不能回答问题。 OP 正在寻找一种方法来比较数组中的 所有 值,而不仅仅是第一个。
    猜你喜欢
    • 2021-05-16
    • 1970-01-01
    • 2018-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-25
    • 1970-01-01
    相关资源
    最近更新 更多