当前位置: 首页 > 知识库问答 >
问题:

对嵌套文档中的记录进行分组

陆子默
2023-03-14
{
"_id" : ObjectId("533e6ab0ef2188940b00002c"),
"uin" : "1396599472869",
"vm" : {
    "0" : {
        "draw" : "01s",
        "count" : "2",
        "type" : "",
        "data" : {
            "title" : "K1"
        },
        "child" : [ 
            "1407484608965"
        ]
    },
    "1407484608965" : {
        "data" : {
            "title" : "K2",
            "draw" : "1407473540857",
            "count" : "1",
            "type" : "Block"
        },
        "child" : [ 
            "1407484647012"
        ]
    },
    "1407484647012" : {
        "data" : {
            "title" : "K3",
            "draw" : "03.8878.98",
            "count" : "1",
            "type" : "SB"
        },
        "child" : [ 
            "1407484762473"
        ]
    },
    "1407484762473" : {
        "data" : {
            "type" : "SB",
            "title" : "D1",
            "draw" : "7984",
            "count" : "1"
        },
        "child" : []
    }
}
}

如何用条件(type=“block”)对所有记录进行分组?

我已尝试:db.itr.aggregate({$match:{“UIN”:“1396599472869”}},{$project:{“VM”:1}},{$group:{_id:null,r1:{$push:“$VM”}}},{$unwind:“$R1”},{$group:{_id:null,r2:{$push:“$R1”}},{$unwind:“$R2”})

但结果仍然是对象的形式,而不是数组的形式。我没有得到“MapReduce”。

共有1个答案

督瑞
2023-03-14

您在这里的问题基本上是与您当前结构化文档的方式有关。在“VM”下实际标识数据点的“keys”的用法并不能很好地与标准查询表单和聚合框架配合使用。

它通常也不是一个很好的模式,因为为了访问“VM”下的任何部分,您需要指定数据的“确切路径”。所以查找类型“block”需要这样做:

db.collection.find({
    "$or": [
        { "vm.0.type": "Block" },
        { "vm.1407484608965.type": "Block" }
        { ... }
    ]
})

等等。您不能像这样“通配符”字段名,所以需要精确的路径。

{
    "_id" : ObjectId("533e6ab0ef2188940b00002c"),
    "uin" : "1396599472869",
    "vm" : [
        {
            "key": 0,
            "draw" : "01s",
            "count" : "2",
            "type" : "",
            "data" : {
                "title" : "K1"
            },
            "child" : [ 
                "1407484608965"
            ]
        },
        {
            "key": "1407484608965",
            "title" : "K2",
            "draw" : "1407473540857",
            "count" : "1",
            "type" : "Block",
            "child" : [ 
                "1407484647012"
            ]
        },
        {
            "key": "1407484647012",
            "title" : "K3",
            "draw" : "03.8878.98",
            "count" : "1",
            "type" : "SB",
            "child" : [ 
                "1407484762473"
            ]
        }
    ]
}
db.collection.find({ "vm.type": "Block" })

或者,如果您想“过滤”数组内容,以便只返回匹配的“子文档”,您可以这样做:

db.collection.aggregate([
    { "$match": { "vm.type": "Block" } },
    { "$unwind": "$vm" },
    { "$match": { "vm.type": "Block" } },
    { "$group": {
        "_id": "$_id",
        "uin": { "$first": "$uin" },
        "vm": { "$push": "$vm" }
    }}
])

对于MongoDB 2.6或更高版本,甚至可能是这样:

db.collection.aggregate([
    { "$match": { "vm.type": "Block" } },
    { "$project": {
        "uin": 1,
        "vm": {
            "$setDifference": [
                { "$map": {
                    "input": "$vm",
                    "as": "el",
                    "in": {"$cond": [
                        { "$eq": [ "$$el.type", "Block" ] },
                        "$$el",
                        false
                    ]}
                }},
                [false]
            ]
        }
    }}
])

或者任何其他操作,简化为遍历,现在数据就是这样结构化的。但是,由于数据当前存在,“遍历键”的唯一选择是使用JavaScript操作,这比以适当的方式查询要慢得多:

db.collection.find(function() {
    return Object.keys(this.vm).some(function(x) { 
        return this.vm[x].type == "Block" 
    })
})
 类似资料:
  • 问题内容: 我在基于所选嵌套文档中的值对文档进行排序时遇到问题。我正在使用这样的设置: 我要检索的是具有所选子代ID的文档,这些文档将按所选子代的大小进行排序。因此查询看起来像: 在此查询中,无论我输入“ order”字段(asc还是desc),返回的文档都是相同的顺序。可能是什么问题? 问题答案: 看起来您构建嵌套过滤器的方式不正确。您在这里列出的内容也不适合我。 但是当我替换这个: 有了这个:

  • 问题内容: 可以说我有以下映射: 然后,我对父文档进行“ _geo_distance”排序,并能够对“ site.point”上的文档进行排序。但是,我还希望嵌套位置在父文档中按“ _geo_distance”排序。 这可能吗?如果是这样,怎么办? 问题答案: 不幸的是,没有(至少现在还没有)。 ElasticSearch中的查询仅标识与该查询匹配的文档以及它们的匹配程度。 要了解嵌套文档的用途,

  • 问题内容: 我正在编写资产管理应用程序。它允许用户通过向资产添加html控件(例如文本字段,选择菜单等)来存储任意资产属性。然后,该属性的JSON表示成为存储在beddb中的资产JSON文档的一部分。资产在ouchdb中具有以下结构: 我不确定将属性放入数组是否是允许基于属性值搜索资产的最佳方法。将属性直接附加到资产作为属性会更好吗?我正在用Elasticsearch做实验。如果我尝试按原样存储文

  • 问题内容: 我正在寻找翻译来更改此内容: 到MongoJava聚合框架。就像是 : 我在文档中找不到答案,我认为它太糟糕了,否则我可能会迷失其中(|哑巴)。 我会先谢谢你 问题答案: 您可以使用以下聚合。

  • 问题内容: 我在ElasticSearch中将以下文档编入索引 我想进行部分更新以清空嵌套属性,所以我应该这样做;因此,我尝试发送部分更新: 但是,此操作无济于事,文档保持不变。如何使用部分更新清空文档中的嵌套对象? 问题答案: 我建议像这样进行脚本更新,它将起作用:

  • 问题内容: 我具有以下数据结构(列表列表) 我希望能够 使用函数对列表重新排序,以便我可以按列表中的每个项目分组。例如,我希望能够按第二列分组(以便所有21列在一起) 使用函数仅显示每个内部列表中的某些值。例如,我想减少此列表,使其仅包含“ 2somename”的第四个字段值 所以列表看起来像这样 问题答案: 对于第一个问题,您应该做的第一件事是使用运算符模块中的itemgetter按第二个字段对