使用 Mongo Native Query 解析 MongoDB DBRef 数组并处理已解析的文档

2024-05-23

我的 MongoDB 集合由 2 个主要集合组成:

1) Maps

{
"_id" : ObjectId("542489232436657966204394"),
"fileName" : "importFile1.json",
"territories" : [ 
    {
        "$ref" : "territories",
        "$id" : ObjectId("5424892224366579662042e9")
    }, 
    {
        "$ref" : "territories",
        "$id" : ObjectId("5424892224366579662042ea")
    }
]
},

{
    "_id" : ObjectId("542489262436657966204398"),
    "fileName" : "importFile2.json",
    "territories" : [ 
        {
            "$ref" : "territories",
            "$id" : ObjectId("542489232436657966204395")
        }
    ],
    "uploadDate" : ISODate("2012-08-22T09:06:40.000Z")
}

2) 领土,在“Map”对象中引用:

{
    "_id" : ObjectId("5424892224366579662042e9"),
    "name" : "Afghanistan",
    "area" : 653958
},
{
    "_id" : ObjectId("5424892224366579662042ea"),
    "name" : "Angola",
    "area" : 1252651
},
{
    "_id" : ObjectId("542489232436657966204395"),
    "name" : "Unknown",
    "area" : 0
}

我的目标是列出每张地图及其累积面积和领土数量。我正在尝试以下查询:

db.maps.aggregate(
    {'$unwind':'$territories'},
    {'$group':{
        '_id':'$fileName',
        'numberOf': {'$sum': '$territories.name'}, 
        'locatedArea':{'$sum':'$territories.area'}
        }
    })

然而,结果显示以下每个值均为 0:

{
    "result" : [ 
        {
            "_id" : "importFile2.json",
            "numberOf" : 0,
            "locatedArea" : 0
        }, 
        {
            "_id" : "importFile1.json",
            "numberOf" : 0,
            "locatedArea" : 0
        }
    ],
    "ok" : 1
}

当尝试访问 Territory 的成员变量(名称和区域)时,我可能做错了什么,但我在 Mongo 文档中找不到这种情况的示例。区域存储为整数,名称存储为字符串。


我在尝试访问 Territory 的成员变量(名称和区域)时可能做错了什么,但我找不到示例 Mongo 文档中就有这样的案例。面积存储为整数,并且 名称作为字符串。

是的,确实是领域"territories"有一个数组数据库参考 http://docs.mongodb.org/manual/reference/database-references/#dbref and not the actual documents. DBRefs是对象contain information with which we can locate the actual documents.

在上面的示例中,您可以清楚地看到这一点,触发以下 mongo 查询:

db.maps.find({"_id":ObjectId("542489232436657966204394")}).forEach(function(do
c){print(doc.territories[0]);})

它将打印 DBRef 对象而不是文档本身:

o/p: DBRef("territories", ObjectId("5424892224366579662042e9"))

so, '$sum': '$territories.name','$sum': '$territories.area'会显示“0”,因为没有诸如name or area.

因此,在执行类似操作之前,您需要解析对文档的引用$territories.name

为了实现你想要的,你可以利用map()函数,因为聚合和 Map-reduce 都支持子查询,并且您已经有了一个独立的map文档,并引用其territories.

实现步骤:

a) get each map
b) resolve the `DBRef`.
c) calculate the total area, and the number of territories.
d) make and return the desired structure.

蒙戈外壳脚本:

db.maps.find().map(function(doc) {
    var territory_refs = doc.territories.map(function(terr_ref) {
        refName = terr_ref.$ref;
        return terr_ref.$id;
    });
    var areaSum = 0;
    db.refName.find({
        "_id" : {
            $in : territory_refs
        }
    }).forEach(function(i) {
        areaSum += i.area;
    });
    return {
        "id" : doc.fileName,
        "noOfTerritories" : territory_refs.length,
        "areaSum" : areaSum
    };
})

o/p:

[
        {
                "id" : "importFile1.json",
                "noOfTerritories" : 2,
                "areaSum" : 1906609
        },
        {
                "id" : "importFile2.json",
                "noOfTerritories" : 1,
                "areaSum" : 0
        }
]

Map-Reduce函数不应该也不能够用于解决DBRefs在服务器端。 看看文档是怎么说的:

地图函数不应出于任何原因访问数据库。

地图功能应该是纯粹的,或者对外部没有影响 功能(即副作用。)

reduce 函数不应该访问数据库,甚至执行 读操作。减少功能不应该影响外部 系统。

此外,一个reduce即使使用了函数(无论如何都无法工作)也永远不会为您的问题调用,因为一个组 w.r.t"fileName" or "ObjectId"您的数据集中始终只有一个文档。

MongoDB 不会对只有一个键的键调用reduce函数 单值

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Mongo Native Query 解析 MongoDB DBRef 数组并处理已解析的文档 的相关文章

随机推荐