我正在对我的收藏品运行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" }
答案 0 :(得分:1)
所以$ first的想法很好。您需要使用$ in过滤集合,然后消除重复项。以下聚合应该有效:
db.myCollection.aggregate([
{
$match: {
deviceId: { $in: ["ABC", "XYZ"] }
}
},
{
$group: {
_id: "$deviceId",
doc: { "$first": "$$CURRENT" }
}
},
{
$replaceRoot: { newRoot: "$doc" }
}
])
doc将为每个组存储第一个完整的文档。在最后一个阶段,我们需要将此文档提升为根,$replaceRoot能够做到这一点。