2012-02-09 110 views
2

据MongoDB的文档,语法$ elemMatch会,

t.find({ x : { $elemMatch : { a : 1, b : { $gt : 1 } } } }) 

我试图和它工作正常。 上面的意思是,它可以找到一个对象{a:1,b:'多于1'}是否存在于数组x中。

我有一个需求,我需要弄清楚,如果数组中的所有对象都存在于数据库中。

例如,假设我有一个数组,

a=[{a:1, b:2},{a:3, b:4}, {a:5, b:6}] 

,我需要找出是否x包含所有的人。 ({x:{$ elemMatch:{a:{$ all:[1]},b:{$ all:[2]}}}}),找出所有包含{a :1,b:2}

但是,如果我尝试,t.find({ x : { $elemMatch : { a : {$all:[1,3]}, b : {$all:[2,4]} } } }),它会失败。我知道这是不正确的。 有什么办法可以做到这一点? Ideallt,它应该是,

t.find({ x : { $elemMatch : {$all:[ {a:1, b:2}, {a:3, b:4}] } }) 

我想,这是行不通的。

回答

1
t.find({$and:[{a:{$elemMatch:{a:1, b:2}}}, {a:{$elemMatch:{a:3, b:4}}}, {a:{$elemMatch:{a:5, b:6}}}]}) 

虽然这不是一个特别高的性能选项。

+0

这似乎解决了我的问题,即使我有第三个元素'c'存在。非常感谢 ! – user644745 2012-02-09 10:51:48

+0

很酷。一定要在你的查询上运行explain()来查看索引打到什么样的性能。 – 2012-02-09 11:01:32

+0

谢谢。幸运的是,我有另一个不需要调用这个查询的实现。 – user644745 2012-02-09 16:10:54

1

不能使用elemMatch这一点,但你完全可以只创建一个查询,检查是否一个整个阵列相匹配:

 
db.items.insert({ 'foo' : 1, 'a' : [{a:1, b:2},{a:3, b:4}, {a:5, b:6}]}); 
db.items.insert({ 'foo' : 1, 'a' : [{a:1, b:2},{a:3, b:4}, {a:8, b:7}]}); 
db.items.find({'a': [{a:1, b:2},{a:3, b:4}, {a:8, b:7}]}); 

{ "_id" : ObjectId("4f3391856e196eca5eaa7518"), "foo" : 1, "a" : [ { "a" : 1, "b" : 2 }, { "a" : 3, "b" : 4 }, { "a" : 8, "b" : 7 } ] } 

然而,对于这项工作的顺序数组中的元素需要与文档和查询相同。下面将找不到任何:

 
db.items.find({'a': [{a:3, b:4},{a:1, b:2}, {a:8, b:7}]}); 

(因为{A:3,B:4}{一个:1,B:2}被交换)。

+0

谢谢。这很好。我的问题是,我有一个'c'也在{a:1,b:2,c:'adsasdasdasd'},我不想比较c。忘了在我上一篇文章中提到这一点。 – user644745 2012-02-09 10:50:43

0

如何:

db.items.find({x : { $all: [ 
    {$elemMatch: {a: 1, b: 2}}, 
    {$elemMatch: {a: 3, b: 4}}, 
    {$elemMatch: {a: 5, b: 6}} 
    ]}} 

退房蒙戈docs

另外,还要注意的文档警告:

在目前的版本中,使用$所有运营商必须扫描 所有符合查询数组中的第一个元素的文档的查询。由于 结果,即使有索引来支持查询,操作可能会长时间运行,特别是当数组中的第一个元素是 不是很有选择性时。