mongo query:添加一个基于另一个字段的排名编号的新字段

时间:2018-05-08 07:33:06

标签: mongodb d3.js d3-force-directed

我是mongo查询的新手。目前我有一个这样的集合,用于创建一个d3力导向图。

{
"_id": "allesgute3",
"nodes": [{
  "id": "bmw@gmail.com",
  "count": 15,
  "nodeUpdatetime": 1525341732
}, {
  "id": "abc@gmail.com",
  "count": 10,
  "nodeUpdatetime": null
}, {
  "id": "xyz@gmail.com",
  "count": 8,
  "nodeUpdatetime": 1525408742
}, {
  "id": "wilson@gmail.com",
  "count": 4,
  "nodeUpdatetime": 1525423847
}, {
  "id": "niv@gmail.com",
  "count": 6,
  "nodeUpdatetime": 1525447758
}, {
  "id": "car@gmail.com",
  "count": 9,
  "nodeUpdatetime": 1525447763
},
{
  "id": "jason@gmail.com",
  "count": 1,
  "nodeUpdatetime": 1525447783
  }
],
"links": [{
  "source": "bmw@gmail.com",
  "target": "jason@gmail.com",
  "timestamp": 1525312111
}, {
  "source": "car@gmail.com",
  "target": "jason@gmail.com",
  "timestamp": 1525334013
}, {
  "source": "bmw@gmail.com",
  "target": "car@gmail.com",
  "timestamp": 1525334118
}]

}

使用mongo查询,我想生成类似这样的输出。基本上对于“节点”下的嵌套数据,添加一个名为“topn”的新字段,并按照从1到5的计数对它们进行排名。其余值为空。有人可以帮忙吗?谢谢!

{
"_id": "allesgute3",
"nodes": [{
  "id": "bmw@gmail.com",
  "count": 15,
  "nodeUpdatetime": 1525341732,
  "topn": 1
}, {
  "id": "abc@gmail.com",
  "count": 10,
  "nodeUpdatetime": null,
  "topn": 2
}, {
  "id": "xyz@gmail.com",
  "count": 8,
  "nodeUpdatetime": 1525408742,
  "topn": 4
}, {
  "id": "wilson@gmail.com",
  "count": 4,
  "nodeUpdatetime": 1525423847,
  "topn": null
}, {
  "id": "niv@gmail.com",
  "count": 6,
  "nodeUpdatetime": 1525447758,
  "topn": 5
}, {
  "id": "car@gmail.com",
  "count": 9,
  "nodeUpdatetime": 1525447763,
  "topn": 3
},
..............

1 个答案:

答案 0 :(得分:1)

以下内容可为您提供所需内容:

db.collection.aggregate({
    $unwind: "$nodes" // flatten the "nodes" array
}, {
    $sort: { "nodes.count": -1 } // sort descending by "count"
}, {
    $group: { // create the original structure again - just with sorted array elements
        _id: "$_id",
        nodes: { "$push": "$nodes" }
    }
}, {
    $addFields: {
        "nodes": {
            $zip: { // zip two arrays together
                inputs: [
                    "$nodes", // the first one being the existing and now sorted "nodes" array
                    { $range: [ 1, 6 ] } // and the second one being [ 1, 2, 3, 4, 5 ]
                ],
                useLongestLength: true // do not stop after five elements but instead continue using a "null" value
            }
        }
    }
}, {
    $addFields: {
        "nodes": {
            $map: { // transform the "nodes" array
                input: "$nodes",
                as: "this",
                in: {
                    $mergeObjects: [ // by merging two objects
                        { $arrayElemAt: [ "$$this", 0] }, // the first sits at array position 0
                        { 
                            topn: { $arrayElemAt: [ "$$this", 1] } // the second will be a new entity witha a "topn" field holding the second element in the array
                        }
                    ]
                }
            }
        }
    }
})