Mongodb 组合阵列中的唯一项
我有一个正在查询的数据集。数据如下所示:Mongodb 组合阵列中的唯一项,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有一个正在查询的数据集。数据如下所示: db.activity.insert( { "_id" : ObjectId("5908e64e3b03ca372dc945d5"), "startDate" : ISODate("2017-05-06T00:00:00Z"), "details" : [ { "code" : "2", "_id" : Obje
db.activity.insert(
{
"_id" : ObjectId("5908e64e3b03ca372dc945d5"),
"startDate" : ISODate("2017-05-06T00:00:00Z"),
"details" : [
{
"code" : "2",
"_id" : ObjectId("5908ebf96ae5003a4471c9b2"),
"walkDistance" : "03",
"jogDistance" : "01",
"runDistance" : "08",
"sprintDistance" : "01"
}
]
}
)
db.activity.insert(
{
"_id" : ObjectId("58f79163bebac50d5b2ae760"),
"startDate" : ISODate("2017-05-07T00:00:00Z"),
"details" : [
{
"code" : "2",
"_id" : ObjectId("58f7948fbebac50d5b2ae7f2"),
"walkDistance" : "01",
"jogDistance" : "02",
"runDistance" : "09",
"sprintDistance" : ""
}
]
}
)
我期望的输出如下所示:
[
{
"_id": null,
"uniqueValues": [
"03",
"01",
"08",
"02",
"09"
]
}
]
为此,我开发了以下代码:
db.activity.aggregate([
{
$facet: {
"walk": [
{$unwind: '$details'},
{$group: {_id: null, uniqueValues: {$addToSet: "$details.walkDistance"}}}
], "jog": [
{$unwind: '$details'},
{$group: {_id: null, uniqueValues: {$addToSet: "$details.jogDistance"}}}
], "run": [
{$unwind: '$details'},
{$group: {_id: null, uniqueValues: {$addToSet: "$details.runDistance"}}}
], "sprint": [
{$unwind: '$details'},
{$group: {_id: null, uniqueValues: {$addToSet: "$details.sprintDistance"}}}
]
}
}])
然而,我仍然得到了4个不同的方面,它们有自己的
\u id:null
和uniqueValues
数组。如何更改查询,使它们都包含在单个数组中,并且“
也被排除在外。$facet
在这里确实不是最好的选择。您实际上应该只应用和筛选结果,并且:
返回结果:
/* 1 */
{
"_id" : null,
"uniqueArray" : [
"09",
"03",
"01",
"02",
"08"
]
}
因此,在使用将所有数组值放入单个数组后,您可以应用将列表缩减为“唯一”值。删除您不需要的“
值
然后,只需应用单数列表和缩减列表,并将其重新组合在一起,以便在文档中只保留唯一的值
您也可以只使用and than and,但其他操作符实际上成本不高,并且在到达文档之前已经将文档的范围缩小到“unique”,从而减少了一些负载。所以这样做更好
事实上,这甚至可以进一步分解,因为我们毕竟在谈论“集合”:
db.activity.aggregate([
{ "$project": {
"_id": 0,
"unique": {
"$setDifference": [
{ "$setUnion": [
"$details.walkDistance",
"$details.jogDistance",
"$details.runDistance",
"$details.sprintDistance"
]},
[""]
]
}
}},
{ "$unwind": "$unique" },
{ "$group": {
"_id": null,
"uniqueArray": { "$addToSet": "$unique" }
}}
])
这意味着整个语句与MongoDB 2.6兼容,或者如果所有表单(如$details.walkDistance
)都是使用$map
以较长的形式写出的,则会兼容:
"$setDifference": [
{ "$setUnion": [
{ "$map": { "input": "$details", "as": "d", "in": "$$d.walkDistance" } },
{ "$map": { "input": "$details", "as": "d", "in": "$$d.jogDistance" } },
{ "$map": { "input": "$details", "as": "d", "in": "$$d.runDistance" } },
{ "$map": { "input": "$details", "as": "d", "in": "$$d.sprintDistance" } }
]},
[""]
]
另一方面,运行会导致对数组中每个属性的整个集合进行“暴力”解析,并在每个过程中处理
$unwind
。因此,这是一种非常低效的获得结果的方法。所以不要这样做。我将发布另一个与此答案直接相关的问题,特别是关于添加$match
语句的问题,因为简单地将它们添加到答案的开头是行不通的。
"$setDifference": [
{ "$setUnion": [
{ "$map": { "input": "$details", "as": "d", "in": "$$d.walkDistance" } },
{ "$map": { "input": "$details", "as": "d", "in": "$$d.jogDistance" } },
{ "$map": { "input": "$details", "as": "d", "in": "$$d.runDistance" } },
{ "$map": { "input": "$details", "as": "d", "in": "$$d.sprintDistance" } }
]},
[""]
]