草庐IT

mongodb - 根据其他字段的值投影数组中存在的特定字段

coder 2023-11-05 原文

概览:

我正在处理的文档中有两个嵌套数组 - contentMetaDatatext_content。 在 contentMetaData 中,我们有 text_contentcontent_flag。根据 content_flag 的值,我需要隐藏 text_content 中的特定字段。

要求:

  • 如果 content_flag 为真,text_content 应该有一个 child - text_note
  • 如果 content_flag 为 false,则 text_content 应该有一个 child - text_description
  • 需要保留结构和其他细节。
  • 文档不应更新;这些值只需要在投影期间隐藏。

使用的版本: Mongo 2.6

示例文档:

{
  "_id": ObjectId("56f8dd19e4b0365115927b0f"),
  "contentId": "cbc91805-2faa-4eff-8f84-02547173c152",
  "contentMetaData": [
    {
      "_id": "1574b58f-b7fa-4cd5-b34f-98beeb657c97",
      "name": "text_content",
      "attributes": [],
      "children": [
        {
          "_id": "97340ecf-fdbd-41e5-a6b2-01cc542f16ee",
          "name": "text_note",
          "value": "abc",
          "type": "java.lang.String",
          "attributes": [],
          "children": [],
          "noOfChildren": 0,
          "positionIndex": 1
        },
        {
          "_id": "19c5a3fb-54a2-4368-a89d-ea1d2554402d",
          "name": "text_description",
          "value": "def",
          "type": "java.lang.String",
          "attributes": [],
          "children": [],
          "noOfChildren": 0,
          "positionIndex": 2
        }
      ],
      "noOfChildren": 2,
      "positionIndex": 1
    },
    {
      "_id": "4e8ef7c9-cffd-4b36-9109-89b263dff3c8",
      "name": "content_flag",
      "value": "true",
      "type": "java.lang.String",
      "attributes": [],
      "children": [],
      "noOfChildren": 0,
      "positionIndex": 2
    }
  ]
}

示例输出:

{
  "_id":  ObjectId("56f8dd19e4b0365115927b0f"),
  "contentId": "cbc91805-2faa-4eff-8f84-02547173c152",
  "contentMetaData": [
    {
      "_id": "1574b58f-b7fa-4cd5-b34f-98beeb657c97",
      "name": "text_content",
      "attributes": [],
      "children": [
        {
          "_id": "97340ecf-fdbd-41e5-a6b2-01cc542f16ee",
          "name": "text_note",
          "value": "abc",
          "type": "java.lang.String",
          "attributes": [],
          "children": [],
          "noOfChildren": 0,
          "positionIndex": 1
        }
      ],
      "noOfChildren": 2,
      "positionIndex": 1
    },
    {
      "_id": "4e8ef7c9-cffd-4b36-9109-89b263dff3c8",
      "name": "content_flag",
      "value": "true",
      "type": "java.lang.String",
      "attributes": [],
      "children": [],
      "noOfChildren": 0,
      "positionIndex": 2
    }
  ]
}

我尝试使用 $map 但它没有用。我尝试使用 $unwind,但无法以所需格式$push 返回数据。

示例 Mongo 代码:

db.content.aggregate([
{
    $project: {
        _id: 1,
        contentId: 1,
        contentMetaData: 1
        tempMetaData: "$contentMetaData"
    }
},
{
    $unwind: "$contentMetaData"
},
{
    $match: {
        "contentMetaData.name": "content_flag"
    }
},
{
    $project: {
        _id: 1,
        contentId: 1,
        contentMetaData: "$tempMetaData",
        content_flag_value: "$contentMetaData.value"
    }
},
{
    $project: {
        _id: 1,
        contentId: 1,
        contentMetaData: 1,
        tempMetaData: "$contentMetaData",
        content_flag_value: 1
    }
},
{
        $unwind: "$contentMetaData"
},
{
        $match: {
                "contentMetaData.name": "text_content"
        }
},
{
        $project: {
                _id: 1,
                contentId: 1,
                contentMetaData: 1,
                tempMetaData: "$contentMetaData",
                content_flag_value: 1,
                text_content : "$contentMetaData.children",
                temp_text_content: "$text_content"
        }
},
{
        $unwind: "$text_content"
},
{
        $group:{
            _id:"$_id",
            contentId:{$first:"$contentId"},
            text_content:
            {$max:
                {$cond: 
                    [
                        {$eq: ["$content_flag_value", "true"]},
                        {$cond:
                            [{$or:[
                                {$eq: ["$text_content.name","wk_link_url"]},
                                {$eq: ["$text_content.name","wk_link_description"]}
                            ]},
                            "$text_content",
                            null]
                        },
                        null
                    ]
                }
            },
            contentMetaData:{$first:"$contentMetaData"}
        }
},
{
        $group:{
            _id:"$_id",
            contentId:{$first:"$contentId"},
            contentMetaData:{$push:{"text_content":"$text_content"}}
        }
},
{
        $project: {
                _id: 0,
                contentId: 1,
                contentMetaData: 1
        }
}]).pretty()

我是 Mongo 的新手。有人可以帮我解决这个问题吗?

最佳答案

您可以尝试以下聚合。

$map 结合 $setDifference 提取 text_contentcontent_flag 数组。

$unwindcontent_flag 文档。

$map 将当前值保存在 text_content$map 中,结合 $setDifference 进行过滤标准上的 children

$setUniontext_contentcontent_flag 数组加入到 contentMetaData

db.collection.aggregate({
    $project: {
        _id: 1,
        contentId: 1,
        text_content: {
            "$setDifference": [{
                    "$map": {
                        "input": "$contentMetaData",
                        "as": "text",
                        "in": {
                            "$cond": [{
                                    $eq: ['$$text.name', "text_content"]
                                },
                                "$$text",
                                false
                            ]
                        }
                    }
                },
                [false]
            ]
        },
        content_flag: {
            "$setDifference": [{
                    "$map": {
                        "input": "$contentMetaData",
                        "as": "content",
                        "in": {
                            "$cond": [{
                                    $eq: ['$$content.name', "content_flag"]
                                },
                                "$$content",
                                false
                            ]
                        }
                    }
                },
                [false]
            ]
        }
    }
}, {
    $unwind: "$content_flag"
}, {
    $project: {
        "_id": 1,
        contentId: 1,
        "contentMetaData": {
            $setUnion: [{
                    $map: {
                        input: "$text_content",
                        as: "text",
                        in: {
                            "_id": "$$text._id",
                            "name": "$$text.name",
                            "attributes": "$$text.attributes",
                            "noOfChildren": "$$text.noOfChildren",
                            "positionIndex": "$$text.positionIndex",
                            "children": {
                                "$setDifference": [{
                                        "$map": {
                                            "input": "$$text.children",
                                            "as": "child",
                                            "in": {
                                                "$cond": [{
                                                        "$cond": [{
                                                            $eq: ["$content_flag.value", "true"]
                                                        }, {
                                                            $eq: ["$$child.name", "text_note"]
                                                        }, {
                                                            $eq: ["$$child.name", "text_description"]
                                                        }]
                                                    },
                                                    "$$child",
                                                    false
                                                ]
                                            }
                                        }
                                    },
                                    [false]
                                ]
                            }
                        }
                    }
                },
                ["$content_flag"]
            ]
        }
    }
})

更新:

$map 结合 $setDifference 提取 content_flag 数组。

$unwindcontent_flag 文档。

$redact 一次遍历文档级别并递归查找 name 字段并执行 $$DESCEND $$PRUNE 标准。

$project 格式化最终响应。

db.collection.aggregate({
    $project: {
        _id: 1,
        contentId: 1,
        contentMetaData: 1,
        content_flag: {
            "$setDifference": [{
                    "$map": {
                        "input": "$contentMetaData",
                        "as": "content",
                        "in": {
                            "$cond": [{
                                    $eq: ['$$content.name', "content_flag"]
                                },
                                "$$content",
                                false
                            ]
                        }
                    }
                },
                [false]
            ]
        }
    }
}, {
    $unwind: "$content_flag"
}, {
    $redact: {
        $cond: [{
                $or: [{
                    $eq: ["$name", "text_content"]
                }, {
                    $not: "$name"
                }, {
                    $eq: ["$name", "content_flag"]
                }, {
                    $and: [{
                        $eq: ["$name", "text_note"]
                    }, {
                        $eq: ["$$ROOT.content_flag.value", "true"]
                    }]
                }, {
                    $and: [{
                        $eq: ["$name", "text_description"]
                    }, {
                        $eq: ["$$ROOT.content_flag.value", "false"]
                    }]
                }]
            },
            "$$DESCEND",
            "$$PRUNE"
        ]
    }
}, {
    $project: {
        _id: 1,
        contentId: 1,
        contentMetaData: 1
    }
});

关于mongodb - 根据其他字段的值投影数组中存在的特定字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41893098/

有关mongodb - 根据其他字段的值投影数组中存在的特定字段的更多相关文章

  1. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  2. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  3. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  4. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  5. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  6. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  7. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  8. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  9. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  10. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

随机推荐