mongodb - 按值排序,其中值在另一个集合中,ID 存储在我们应用排序的集合中

标签 mongodb mongodb-query

我有下一个情况。

parameters 集合中,我的文档具有键 groups,其中值是来自另一个集合的文档的 ids。这有点像引用另一个集合的外键。

在另一个集合中,我们有对应于存储在主 parameters 集合中的 '_ids' 的文档。

这是parameters 集合中的一个示例文档:

{
    "_id" : ObjectId("538726134ba2222c0c0248b6"),
    "name" : "Potta",
    "groups" : [ 
        "54c91b2c4ba222182e636943"
    ]
}

我需要按组排序,但正如您在主集合组中看到的那样,值是 ID,但我想按组名排序。

这是 groups 集合中的一个示例集合。

{
    "_id" : ObjectId("54c91b2c4ba222182e636943"),
    "name" : "Group 01",
}

这在 Mongo DB 中可以实现吗?

谢谢

最佳答案

给定数据是

> db.parameters.find({})
{ "_id" : ObjectId("56cac0cd0b5a1ffab1bd6c12"), "name" : "potta", "groups" : [ "
123", "234" ] }
> db.groups.find({})
{ "_id" : "123", "name" : "Group01" }
{ "_id" : "234", "name" : "Group02" }

mongodb 3.2下,可以通过$lookup来完成对同一数据库中的未分片集合执行左外连接,然后按如下所示排序组名。

> db.parameters.aggregate([
                          {$unwind: '$groups'}, 
                          {$lookup: {
                                    from: 'groups', 
                                    localField: 'groups', 
                                    foreignField: '_id', 
                                    as: 'gr'}},
                           {$sort: {'gr.name': 1}}])

对于3.2,请尝试如下操作

> var pa = db.parameters.find({});
> pa.forEach(function(doc) {
                var ret = db.groups
                            .find({_id: {$in: doc.groups}})
                            .sort({name: 1}); 
                ret.forEach(printjson)
});

或者您可以通过 mapReduce 完成如下

// emit group id from parameters collection
> var map_param = function() { 
            var that = this; 
            this.groups.forEach(function(g){emit(that._id, g);})};

// emit group id and name from group collection
> var map_group = function() {emit(this._id, this.name);}

// combine those results from map functions above
> var r = function(k, v) {
            var result = {id: '', name: ''};
            v.forEach(function(val){
                   if (val.id !== null){ result.id = val;} 
                   if (val.name !== null) {result.name = val;}
            }); 
            return result;};

> db.parameters.mapReduce(map_param, r, {out: {reduce: 'joined'}})

> db.groups.mapReduce(map_group, r, {out: {reduce: 'joined'}, sort: {name: 1}})

最终,排序后的结果在 joined 集合中。

关于mongodb - 按值排序,其中值在另一个集合中,ID 存储在我们应用排序的集合中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35548179/

相关文章:

mongodb - MongoDB oplog 操作字母是什么意思?

javascript - 如何使用Mongoose使用MongoDB事务?

mongodb - 在一个查询中计算和匹配相关文档

ajax - Mongodb 总行数限制

java - MongoOperations - upsert/findAndModify 删除 mongo 中的所有字段

javascript - 从 $arrayElemAt 结果中选择字段

javascript - MongoDB:如何返回 JSON 中的特定字段和特定子文档

node.js - nodejs + mongo + find + $和错误: Can't canonicalize query

java - MongoDB 在 Java 中按日期查询

java - 如何在 applicationContext 中停止我们模拟的 MongoDb 仅 1 个负面测试用例?