在mongodb中使用带有多个条件的$ redact

时间:2017-08-28 14:21:31

标签: mongodb

我有一个下面的mongo集合“test”,它在文档的顶层没有“tags”字段。

{
    "_id" : 1,
    "title" : "123 Department Report",
    "year" : 2014,
    "subsections" : [
        {
            "subtitle" : "Section 1: Overview",
            "tags" : "SI",
            "content" : "Section 1: This is the content of section 1."
        },
        {
            "subtitle" : "Section 2: Analysis",
            "tags" : "STLW",
            "content" : "Section 2: This is the content of section 2."
        },
        {
            "subtitle" : "Section 3: Budgeting",
            "tags" : "TK",
            "content" : {
                "text" : "Section 3: This is the content of section3.",
                "tags" : "HCS"
            }
        }
    ]
}

我的要求是选择仅具有“标签”值“STLW”的子部分。 我正在运行以下聚合查询。

db.test.aggregate([
  { $redact: {
       $cond: {          
          if: { $or: [ {$ifNull: ['$tags', true]}, {$eq: [ "$tags" , 'STLW' ]} ] },
          then: "$$DESCEND",
          else: "$$PRUNE"
        }
      }
  }
]

但是在运行查询时,我将获得以下输出中的所有子文档:

{
    "_id" : 1,
    "title" : "123 Department Report",
    "year" : 2014,
    "subsections" : [
        {
            "subtitle" : "Section 1: Overview",
            "tags" : "SI",
            "content" : "Section 1: This is the content of section 1."
        },
        {
            "subtitle" : "Section 2: Analysis",
            "tags" : "STLW",
            "content" : "Section 2: This is the content of section 2."
        },
        {
            "subtitle" : "Section 3: Budgeting",
            "tags" : "TK",
            "content" : {
                "text" : "Section 3: This is the content of section3.",
                "tags" : "HCS"
            }
        }
    ]
}

但是,我想要以下输出。

{
    "_id" : 1,
    "title" : "123 Department Report",
    "year" : 2014,
    "subsections" : 
        {
            "subtitle" : "Section 2: Analysis",
            "tags" : "STLW",
            "content" : "Section 2: This is the content of section 2."
        }
}

任何人都能帮助我实现这个目标吗?

感谢...........

1 个答案:

答案 0 :(得分:1)

现在可能有点晚了,但万一其他人还在寻找类似的东西。

如果你有Mongo 3.4,你可以使用$ filter运算符和$ addFields阶段轻松实现。如果你有3.2,你只需要在所有原始字段中添加一个投影(而不是使用addFields快捷方式)。

db.test.aggregate([
{
    $addFields:{
        subsections:{
            $filter:{
                input:"$subsections",
                cond: {$eq:["$$this.tags","STLW"]}
            }
        }
    }
}
])

会产生这样的回应:

{
    "_id" : 1,
    "title" : "123 Department Report",
    "year" : 2014,
    "subsections" : [ 
        {
            "subtitle" : "Section 2: Analysis",
            "tags" : "STLW",
            "content" : "Section 2: This is the content of section 2."
        }
    ]
}

或者,如果你想继续使用$ redact:

db.test.aggregate([
{$redact:{
    $cond: {
        if: {
            $and:[
                {$ifNull:["$tags",false]},
                {$ne:["$tags","STLW"]}
            ]
        },
        then: "$$PRUNE",
        else: "$$DESCEND"
    }
}}
]);