【问题标题】:Mongo Aggregation where query is having child elements that create rootMongo 聚合,其中查询具有创建根的子元素
【发布时间】:2021-06-15 19:19:06
【问题描述】:

我有一个在后端生成的查询,在该项目中,路径是基于根元素构建的。

{
  data: [
    {
      $project: {
        'Source.Code': {
          $ifNull: [
            '$Source.Code',
            '$$REMOVE'
          ]
        },
        'Source.Description': {
          $ifNull: [
            '$Source.Description',
            '$$REMOVE'
          ]
        },
        'Source._id': {
          $ifNull: [
            '$Source._id',
            '$$REMOVE'
          ]
        }
      }
    }
  ]
}

上面是投影,如您所见,Source 是根据Source 文档中的字段创建的。如果我正在为子字段做我的问题,我想在Source 上检查$ifNull 并在根本没有文档的情况下将其删除。类似的东西

      {
        'Source': {
          $ifNull: [
            '$Source',
            '$$REMOVE'
          ]
        }

我不确定如何在聚合中构建这样的查询。这里 Source 是一个对象,它有多个字段,我想检查 Source 上的空值,如果它不为空,则检查其所有字段并相应地添加到 Source

{
Source: {
    Code: "Code",
    Description: "test",
    _id: "SomeID"
  }
}

如果描述为空,那么

{
Source: {
    Code: "Code",
    _id: "SomeID"
  }
}

编辑 1:
现在我想添加一个案例,其中我有对象 Source 并且它有可以翻译的字段。我所说的可翻译的意思是它们是 i18n 字段,其中包含语言字段。所以考虑下面的例子

{
Source: {
    Code: "Code",
    Description: {
       "en":"test",
       "fr": "testfr",
       "def": "test"
},
    _id: "SomeID"
  }
}

所以现在从我之前提到的查询开始

{
  data: [
    {
      $project: {
        'Source.Code': {
          $ifNull: [
            '$Source.Code',
            '$$REMOVE'
          ]
        },
        'Source.Description': {
          $ifNull: [
            '$Source.Description.en',
            '$$REMOVE'
          ]
        },
        'Source._id': {
          $ifNull: [
            '$Source._id',
            '$$REMOVE'
          ]
        }
      }
    }
  ]
}

因此,Source.Description.en 将 .en 附加到路径以从 Description 中获取 en。如何更改此边缘案例的查询?

【问题讨论】:

  • 是对象类型的源字段数组吗?
  • 它是一个对象。我想检查 $ifNull 里面的所有字段以及它。因此,这就像首先检查 Source 是否为空或为空,如果不是,则检查其内部每个字段的字段是否为空。

标签: mongodb aggregation-framework


【解决方案1】:
  • $objectToArraySource 对象转换为数组键值格式
  • $filter 迭代上述转换数组的循环并按值过滤不为空
  • $arrayToObject 将键值转换回对象
  • $addFieldsdesscription 得到en
  • $cond 检查其是否为空对象然后删除,否则返回
db.collection.aggregate([
  {
    $project: {
      Source: {
        $arrayToObject: {
          $filter: {
            input: { $objectToArray: "$Source" },
            cond: { $ne: ["$$this.v", null] }
          }
        }
      }
    }
  },
  { $addFields: { "Source.Description": "$Source.Description.en" } },
  {
    $project: {
      Source: {
        $cond: [{ $eq: ["$Source", {}] }, "$$REMOVE", "$Source"]
      }
    }
  }
])

Playground

【讨论】:

  • 如果我有一个可翻译的字段,我需要将 .en 之类的区域设置附加到对象内的字段中。我也想检查一下。我该怎么做?
  • 我刚刚通过编辑更新了问题,请看一下。谢谢
  • playground,只需要添加一个stage。
  • 但它在结果中添加了 Source 的空对象。如果 Source 为空,我想删除。 $addFields 正在帮助处理语言文档,但如果它为空,它会添加空对象
  • playground
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-02
  • 2020-11-03
  • 1970-01-01
  • 1970-01-01
  • 2016-11-03
  • 2015-03-20
相关资源
最近更新 更多