Mongodb 将数组内容筛选到包含$concatarray的查询
给定这个函数,我有一个正在查询的数据集。数据如下所示:Mongodb 将数组内容筛选到包含$concatarray的查询,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"
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" : ""
}
]
}
)
使用此功能,感谢Neil Lunn,我能够获得所需的输出:
db.activity.aggregate([
{ "$project": {
"_id": 0,
"unique": {
"$filter": {
"input": {
"$setDifference": [
{ "$concatArrays": [
"$details.walkDistance",
"$details.jogDistance",
"$details.runDistance",
"$details.sprintDistance"
]},
[]
]
},
"cond": { "$ne": [ "$$this", "" ] }
}
}
}},
{ "$unwind": "$unique" },
{ "$group": {
"_id": null,
"uniqueArray": { "$addToSet": "$unique" }
}}
])
但是,我无法在开头添加匹配语句
db.activity.aggregate([
{$match: {"startDate" : ISODate("2017-05-06T00:00:00Z"), "details.code": "2" },
{$unwind: '$details'},
{$match: {"startDate" : ISODate("2017-05-06T00:00:00Z"), "details.code": "2" },
{ "$project": {
"_id": 0,
"unique": {
"$filter": {
"input": {
"$setDifference": [
{ "$concatArrays": [
"$details.walkDistance",
"$details.jogDistance",
"$details.runDistance",
"$details.sprintDistance"
]},
[]
]
},
"cond": { "$ne": [ "$$this", "" ] }
}
}
}},
{ "$unwind": "$unique" },
{ "$group": {
"_id": null,
"uniqueArray": { "$addToSet": "$unique" }
}}
])
因为它会给出以下错误消息:
> $concatArrays only supports arrays, not string
如何修改此查询,以便添加$match
语句?不要添加要馈送到的数组。而是仅应用于提取匹配值。如前所述,我们可以使用“唯一连接”来代替:
db.activity.aggregate([
{ "$match": { "startDate" : ISODate("2017-05-06T00:00:00Z"), "details.code": "2" } },
{ "$project": {
"_id": 0,
"unique": {
"$let": {
"vars": {
"filtered": {
"$filter": {
"input": "$details",
"cond": { "$eq": [ "$$this.code", "2" ] }
}
}
},
"in": {
"$setDifference": [
{ "$setUnion": [
"$$filtered.walkDistance",
"$$filtered.jogDistance",
"$$filtered.runDistance",
"$$filtered.sprintDistance"
]},
[""]
]
}
}
}
}},
{ "$unwind": "$unique" },
{ "$group": {
"_id": null,
"uniqueArray": { "$addToSet": "$unique" }
}}
])
使用将使语法更加简洁,因为您不需要将多个and语句“inline”指定为的源代码,这与
$match
无关,而与$unwind
有关。因为一旦你这样做了,“细节”就不再是一个“数组”。那你为什么这么做呢?我的$match
语句的一部分用于详细信息。code
,所以我不需要它吗?我想我不需要!非常感谢您的澄清!