我的文档集如下所示:
[
{
"_id": {
"$oid": "596e004151cc92046c28dd39"
},
"routes": [
{
"legs": [
{
"LegId":0,
"end_address": "B",
"start_address": "A",
"price":123
},
{
"LegId":1,
"end_address": "C",
"start_address": "B",
"price":123
},
{
"LegId":2,
"end_address": "D",
"start_address": "C",
"price":120
},
{
"LegId":3,
"end_address": "E",
"start_address": "D",
"price":125
}
]
}
],
"status": "OK",
"Date": {
"$date": "2017-07-18T12:34:07.781Z"
}
},
{
"_id": {
"$oid": "596e007d51cc9231a8117607"
},
"routes": [
{
"legs": [
{
"LegId":0,
"end_address": "E",
"start_address": "F",
"price":300
},
{
"LegId":1,
"end_address": "D",
"start_address": "E",
"price":200
},
{
"LegId":2,
"end_address": "C",
"start_address": "D",
"price":200
},
{
"LegId":3,
"end_address": "B",
"start_address": "C",
"price":200
}
]
}
],
"status": "OK",
"Date": {
"$date": "2017-07-18T12:35:09.121Z"
}
}
]
我需要投影 Status、Date 以及 StartAddress="A 和 end Address="D" 之间腿的总价(通过传递起始地址和结束地址找到腿 ID,并使用 $gt 和 $lt legId)
仅供参考:至于查找顶级文档,我在每个文档中使用祖先字段来过滤 2 个所需的文档。
对不起,如果我对语言感到困惑。
$filter
、$map
和$sum
的应用:
db.collection.aggregate([
// Still actually query for documents that meet the later filter conditions
{ "$match": {
"routes": {
"$elemMatch": {
"legs": {
"$elemMatch": {
"start_address": { "$gte": "A" },
"end_address": { "$lte": "D" }
}
}
}
}
}},
// Just return the wanted array fields and the sum of the matching inner
{ "$addFields": {
"routes": {
"$map": {
"input": "$routes",
"as": "r",
"in": {
"Status": "$$r.Status",
"Date": "$$r.Date",
"totalPrice": {
"$sum": {
"$map": {
"input": {
"$filter": {
"input": "$$r.legs",
"as": "l",
"cond": {
"$and": [
{ "$gte": [ "$$l.start_address", "A" ] },
{ "$lte": [ "$$l.end_address", "D" ] }
]
}
}
},
"as": "l",
"in": "$$l.price"
}
}
}
}
}
}
}}
])
$map
迭代外部 "routes"
数组并简单地返回所有这些条目。如果我们想在这里“过滤”任何东西,那么我们将类似地应用一个$filter
到这个"input"
的
$map
,但是你的问题除了返回"totalPrice"
之外没有任何意义。
所以其他数组属性只是在输出中命名,就像任何其他语言实现中的“map”一样。对于
"totalPrice"
,您显然想要$sum
,但是我们需要使用$filter
来匹配数组元素,然后使用$map
来获取特定字段"price"
来实际喂养$sum
.
$filter
的参数在 "cond"
中指定,您使用 $gte
和 $lte
的“逻辑形式”,它们返回参数预期的布尔结果,并且仅然后保留那些数组成员。 $and
通过确保两个内部参数都需要返回 true
来扩展逻辑条件,以便返回 true
.