2016-04-25 141 views
1

我维护一个房间表,它由与会话相关的记录组成。我想获得两个用户之间的房间ID,所以使用findOne查询,但它带来了其他记录,并不能满足我的需要。 建议我查询出错的地方。MongoDB问题与findOne查询

如果我给查询: rooms.findOne({ "userId" :"800", "userId" :"600"}); 我expectng的fsny11z742kpgb9对话ID,但是它给6puebew70kke29

{ 
    "_id": ObjectId("571c5724db62826826d28d08"), 
    "conversationId": "6puebew70kke29", 
    "userId": "600", 
    "firstName": "Test", 
    "profileImagePath": "", 
    "created": ISODate("2016-04-24T05:18:28.753Z"), 
    "__v": 0 
} 
{ 
    "_id": ObjectId("571c5724db62826826d28d09"), 
    "conversationId": "6puebew70kke29", 
    "userId": "900", 
    "firstName": "User", 
    "profileImagePath": "", 
    "created": ISODate("2016-04-24T05:18:28.754Z"), 
    "__v": 0 
} 

{ 
    "_id": ObjectId("571c574edb62826826d28d0b"), 
    "conversationId": "fsny11z742kpgb9", 
    "userId": "600", 
    "firstName": "FitTest", 
    "profileImagePath": "", 
    "created": ISODate("2016-04-24T05:19:10.192Z"), 
    "__v": 0 
} 

{ 
    "_id": ObjectId("571c574edb62826826d28d0c"), 
    "conversationId": "fsny11z742kpgb9", 
    "userId": "800", 
    "firstName": "Dev", 
    "profileImagePath": "", 
    "created": ISODate("2016-04-24T05:19:10.193Z"), 
    "__v": 0 
} 
+0

在查询中,为什么要编写两次UserID? –

+0

数据中似乎没有任何'类型'字段。所以我想知道为什么一个带有'type'的查询:'PRIVATE'返回一些东西。 –

+0

我想convesationID这涉及两个用户tats为什么给userId两次 – Karthik

回答

4

您必须使用聚合来完成此操作。

rooms.aggregate([ 
 
    { $group: { _id: '$conversationId', users: { $push: '$userId' } } }, 
 
    { $match: { users: { $all: ['800', '600'] }, groupType: 'PRIVATE' } }, 
 
])

+0

这个。我相信你应该聚合,以便这两个UserId的匹配。 –

+0

@MathieuLordon:假设我有一个群组类型private或group,无论如何要添加像groupType这样的另一个字段:'PRIVATE'那样? – Karthik

+0

我编辑了我的帖子以仅匹配私人对话。为了获得更好的性能,您还可以在$ group阶段之前按groupType进行过滤(当然,在groupType上有一个索引)。 –

1

的findOne()操作返回根据反映的磁盘上的文件的顺序的自然顺序的第一个文档,见mongodb docs

其次,作为findOne()操作的参数提供的查询文档包含userId的两个值,这与$in operator不一样。后者覆盖第一个。

如马修建议的,一个适当的查找将是使用一个聚合管道有两个步骤:

rooms.aggregate([ 
    { $group: { _id: '$conversationId', users: { $push: '$userId' } } }, 
    { $match: { users: { $all: ['800', '600'] }, groupType: 'PRIVATE' } }, 
]) 
  1. 创建具有ID相匹配的会话ID和类型的阵列包含所有的用户id字段列表( $ group stage)
  2. 筛选出所有条目,其中用户数组包含您正在查找的两个用户的ID。 ($ match stage)

请记住,这将返回所有这两个用户的对话。