如何在位置3上找到$ match的文档(只有数组“ndr”中的最后一项)。聚合必须仅搜索ndr。
的最后一个数组项 {
"_id" : ObjectId("58bd5c63a3d24b4a2e4cde03"),
"name" : "great document",
"country" : "us_us",
"cdate" : ISODate("2017-03-06T12:56:03.405Z"),
"nodes" : [
{
"node" : 3244343,
"name" : "Best Node ever",
"ndr" : [
{
"position" : 7,
"cdate" : ISODate("2017-03-06T10:55:20.000Z")
},
{
"position" : 3,
"cdate" : ISODate("2017-03-06T10:55:20.000Z")
}
]
}
],
}
聚合后我需要这个结果
{
"name" : "great document",
"country" : "us_us",
"cdate" : ISODate("2017-03-06T12:56:03.405Z"),
"nodes" : [
{
"node" : 3244343,
"name" : "Best Node ever",
"ndr" : [
{
"position" : 3,
"cdate" : ISODate("2017-03-06T10:55:20.000Z")
}
]
}
]
}
我希望有人能帮助我。
答案 0 :(得分:0)
您将需要展开两个嵌套数组。
db.<collection>.aggregate([
{ $unwind: '$nodes' },
{ $unwind: '$nodes.ndr'},
{ $group: {'_id':{'_id':'$_id', 'nodeID', '$nodes.node' },
'name':{'$last':'$name'},
'country':{'$last':'$country'},
'cdate':{'$last':'$cdate'},
'nodes':{'$last':'$nodes'}
}
},
{ $match : { nodes.ndr.position: 3 } }
]);
从这里你可以用$ group重新组合聚合结果并进行投影。我不确定你的最终结果应该是什么。
答案 1 :(得分:0)
您可以尝试使用Mongo 3.4版本进行以下聚合。
以下查询使用(-1)
数组中的$arrayElemAt
运算符查找最后一项ndr
,并使用last
运算符将变量存储在$let
中{ {1}}并使用nodes
表示法将last
变量position
值与$$
进行比较,并将3
元素包含在数组nbr
中找到并返回空数组。
[]
运算符访问$map
数组中的nbr
数组,并在映射其余nodes
字段时投影更新的nbr
数组。
nodes
阶段会覆盖现有的$addFields
新nodes
,同时保留所有其他字段。
nodes
<强>更新强>
如果找到与给定过滤器匹配的位置,您可以尝试db.collection.aggregate([{
$addFields: {
nodes: {
$map: {
input: "$nodes",
as: "value",
in: {
node: "$$value.node",
name: "$$value.name",
ndr: {
$let: {
vars: {
last: {
$arrayElemAt: ["$$value.ndr", -1]
}
},
in: {
$cond: [{
$eq: ["$$last.position", 3]
},
["$$last"],
[]
]
}
}
}
}
}
}
}
}]);
保留整个文档。
$redact
根据每个节点$map
位置值和true
的过滤器投影false
,nbr
值将检查前一个布尔值每个文档的值并返回$anyElementTrue
或true
值,false
将使用上述比较中的booelan值;保留的真值和删除文档的假值。
$redact
答案 2 :(得分:0)
Woodsy的解决方案对我来说非常适合。现在我需要计算每个节点的$ avg以及从“node.bsr.rank”以百分比(loos或win)进入给定数量的最后几天之间的开发。
喜欢这个结果
{
"name" : "great document",
"country" : "us_us",
"cdate" : ISODate("2017-03-06T12:56:03.405Z"),
"nodes" : [
{
"node" : 3244343,
"name" : "Best Node ever",
"avg_rank": 4,
"historie": 120,
"ndr" : [
{
"position" : 3,
"cdate" : ISODate("2017-03-06T10:55:20.000Z")
}
]
}
]
}