匹配所有字段满足给定条件的元素

时间:2014-09-26 19:36:14

标签: mongodb nosql

我有一个'对象',它有一个列表字段'元素',另一方面, 还有另一个列表字段' items',反过来,它可以是两种' a'或者' b'如下:

use test;

db.objects.insert({
  "_id" : "e81d80ffae684cfd9147bc4017c42b9a",
  "elements" : [{
      "items" : [
          {"id" : "3632407fca17f4a1307c96659ebe32762ffe5d22", "kind" : "a"},
          {"id" : "3632407fca17f4a1307c96659ebe32762ffe5d22", "kind" : "b"}
      ]
  }]
})

db.objects.insert({
  "_id" : "1e0fd210530d4580af95b8eb7f2b38df",
  "elements" : [ 
        {
            "items" : [
                {"id" : "27d6fabba14a4473b7786258127ec68b", "kind" : "a"},
                {"id" : "6c9c223391ec46078ef02e00683fe167", "kind" : "b"}
            ]
        },
        {
            "items" : [
                {"id" : "3fd8631ab15e46c7982093bcb08c868d", "kind" : "a"}
            ]
        }
    ]
})

我需要执行一个匹配任何元素包含所有项目的所有对象的查询 不同于' b'。

是否可以在不创建Javascript函数的情况下完成Mongo查询。

3 个答案:

答案 0 :(得分:2)

您可以使用$elemMatch$ne执行该查询:

db.objects.find({
    elements: {$elemMatch: {'items.kind': {$ne: 'b'}}}
})

这将找到至少有一个elements元素的文档,其中itemskind 'b'数组元素没有{ "_id" : "1e0fd210530d4580af95b8eb7f2b38df", "elements" : [ { "items" : [ { "id" : "27d6fabba14a4473b7786258127ec68b", "kind" : "a" }, { "id" : "6c9c223391ec46078ef02e00683fe167", "kind" : "b" } ] }, { "items" : [ { "id" : "3fd8631ab15e46c7982093bcb08c868d", "kind" : "a" } ] } ] }

输出:

{{1}}

答案 1 :(得分:1)

使用JS

db.objects.find(
    {
      '$where': 'this.elements.map(function(element){return element.items.every(function(item){return item.kind !== "b"})}).indexOf(true) >= 0'
    }
)  

答案 2 :(得分:0)

如果您只关心ID,可以使用聚合管道:

> db.objects.aggregate(
...   {$unwind: "$elements"}, 
...   {$project: {_id:1, item_id:"$elements.items.id", kind: "$elements.items.kind"}},
...   {$match: {kind: {$ne: "b"}}}
... )

之后,您可以使用$in查询来获取文档。也许使用$elemMatch会更快。