在Mongo中的`IN`查询的每个结果中返回第一个结果

时间:2017-12-14 14:47:58

标签: mongodb

我正在对我的收藏品运行IN查询。 这是我的查询结构:

 db.myCollection.find ( 
   { deviceId : { $in : [ "ABC", "XYZ" .. ] } 
 })

我知道一个事实,每个都会返回多行,但我只想获得每个行的第一个结果。

我查看了$first聚合函数,但看不到它适合我的情况。

我可以一次针对每个ID进行findOne查询,并将结果合并到用Java编写的客户端代码中。但是可能有很多这些ID,我希望每次都减少网络往返。

EDIT。添加示例以获得更清晰。

我的收藏中的示例数据:

{ "_id" : 1, "deviceSerial" : 1, "deviceId" : "ABC" }
{ "_id" : 2, "deviceSerial" : 2, "deviceId" : "XYZ" }
{ "_id" : 3, "deviceSerial" : 3, "deviceId" : "LMN" }
{ "_id" : 4, "deviceSerial" : 4, "deviceId" : "PQR" }
{ "_id" : 5, "deviceSerial" : 5, "deviceId" : "SDS" }
{ "_id" : 6, "deviceSerial" : 6, "deviceId" : "KLP" }

现在,如果我使用{ deviceId : { $in : [ "LMN", "XYZ" ] }

进行查询

预期输出(排序无关紧要):

{ "_id" : 2, "deviceSerial" : 2, "deviceId" : "XYZ" }  
{ "_id" : 3, "deviceSerial" : 3, "deviceId" : "LMN" }

1 个答案:

答案 0 :(得分:1)

所以$ first的想法很好。您需要使用$ in过滤集合,然后消除重复项。以下聚合应该有效:

db.myCollection.aggregate([
    {
        $match: {
            deviceId: { $in: ["ABC", "XYZ"] }
        }
    },
    {
        $group: {
            _id: "$deviceId",
            doc: { "$first": "$$CURRENT" }
        }
    },    
    {
        $replaceRoot: { newRoot: "$doc" }
    }
])

doc将为每个组存储第一个完整的文档。在最后一个阶段,我们需要将此文档提升为根,$replaceRoot能够做到这一点。