2013-05-02 69 views
1

如何查询与数组中对象的确切字段匹配的集合?如何查询与数组中对象的确切字段匹配的集合

由于测试用例更加明确,因此这里是要通过的测试。

a = Invitation.create(guests: [ Guest.new(player: 'bbb'), Guest.new(player: 'ccc') ]) 
b = Invitation.create(guests: [ Guest.new(player: 'ccc'), Guest.new(player: 'bbb') ]) 
c = Invitation.create(guests: [ Guest.new(player: 'bbb'), Guest.new(player: 'ccc'), Guest.new(player: 'ddd') ]) 

# Request to find invitation with bbb and ccc as player_id of guests, regardless the order. 
result = Invitation.collection.find(...) 
assert_equal result, [ a, b ] 

我用例是一个邀请系统,其中的客人相同的组合可以不存在,所以当发送一个新的邀请,我需要检查,如果一个完全相同的人(不管它们的顺序)。

注:我使用一个Guest对象数组,因为它携带一些额外的数据。这里是一个示例数据集(https://gist.github.com/anonymous/5507735)。

+0

你能提供一个mongo记录的例子吗? db.Invitation.findOne()会做的。 – shargors 2013-05-02 19:05:47

+0

我编辑帖子以添加示例数据集(https://gist.github.com/anonymous/5507735)。 – 2013-05-03 07:35:58

回答

1

根据nyde1319的回答;这种感觉稍微的hackish,但因为这里有没有其他解答得好:

db.invitation.find({'guests.player':{'$all':['bbb','ccc']}, guests: {$size: 2}}) 

在课程{$size: 2}数2取决于数组的长度。

+0

它运作良好。谢谢! – 2013-05-03 18:00:05

1

也许$all是你所需要的。我不知道你正在使用的ORM还是什么模式,但是这里有一个样本蒙戈外壳输出:

> db.invitation.find({'guests.player':{'$all':['bbb','ccc']}}) 
{ "_id" : ObjectId("518319079468428b381d3563"), "guests" : [ { "player" : "bbb" }, { "player" : "ccc" } ] } 
{ "_id" : ObjectId("518319239468428b381d3566"), "guests" : [ { "player" : "ccc" }, { "player" : "bbb" } ] } 
{ "_id" : ObjectId("518319b39468428b381d3567"), "guests" : [ { "player" : "ccc" }, { "player" : "bbb" }, { "player" : "ddd" } ] } 

如果你只想要那些含有'bbb'只有'ccc',你可以尝试以下方法:

db.inv.find({'guests.player':{$all:['bbb','ccc']}, 
    'guests':{$not:{$elemMatch:{'player':{$nin:['bbb','ccc']}}}}}) 

这给:

[ 
    { "_id" : ObjectId("518319079468428b381d3563"), 
     "guests" : [ { "player" : "bbb" }, { "player" : "ccc" } ] }, 
    { "_id" : ObjectId("518319239468428b381d3566"), 
     "guests" : [ { "player" : "ccc" }, { "player" : "bbb" } ] } 
] 

如果你想'bbb''ccc',只需更换$all$in。这在某种程度上是异或实现,但我不确定它是否覆盖了您的所有用例。

+0

问题是我不想要第三个记录。我只想邀请BBB和CCC球员(不管顺序如何)。我不想要那些含有BBB,CCC和DDD的。 – 2013-05-03 07:26:24

+0

请参阅我的编辑。 – MervS 2013-05-03 11:03:26

+0

谢谢。我相信Juho的回答是更好的选择。 – 2013-05-03 18:02:13

相关问题