如何仅投影MongoDB阵列中的字段?

发布于 2025-01-23 04:30:55 字数 650 浏览 1 评论 0原文

有一个文档架构,该模式具有一个名为“ updatedFields”的数组字段,其中包含一些您会在“ OldDocument”“ newDocument”对象。这是它的图片。

现在我只想投射“ updatedFields”中存在的那些字段来自“ newDocument” and 和“ olddocument” 如下:

 $project : { 
    "oldDocument.Modified":1,
    "oldDocument.Status":1,
    "newDocument.Modified":1,
    "newDocument.Status":1
 } 

有人知道如何在数组中的字段名称上构建项目子句基础吗?我需要mongoDB查询,而不是JS代码。

there is a document schema that has an array field called "updatedFields" which contains some fields names that you will find in "oldDocument" and
"newDocument" objects. Here is its picture.

enter image description here

Now I want to project only those fields which exist in "updatedFields" array from "newDocument" and "oldDocument" like below:

 $project : { 
    "oldDocument.Modified":1,
    "oldDocument.Status":1,
    "newDocument.Modified":1,
    "newDocument.Status":1
 } 

Does anyone know how to build the project clause base on the fields' names in the array? I need a MongoDB query, not js code.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

飞烟轻若梦 2025-01-30 04:30:55

您可以使用$ objectToArray为了将键格式化为值,$ filter根据UPDATEDFIELDS array,然后使用$ $ ArrayToObject将它们再次制成键。

编辑:根据评论的请求,使用$ MAP在过滤器内部使用将日期投入到字符串。

像这样的事情:

db.collection.aggregate([
  {
    $project: {
      oldDocumentArr: {$objectToArray: "$oldDocument"},
      newDocumentArr: {$objectToArray: "$newDocument"},
      updatedFields: 1
    }
  },
  {
    $project: {
      oldDocumentFilter: {
        $map: {
          input: {
            $filter: {
              input: "$oldDocumentArr",
              as: "item",
              cond: {$in: ["$item.k", "$updatedFields"]
              }
            }
          },
          "as": "obj",
          "in": {
            "k": "$obj.k",
            "v": {$toString: "$obj.v"}
          }
        }
      },
      newDocumentFilter: {
        $map: {
          input: {
            $filter: {
              input: "$newDocumentArr",
              as: "item",
              cond: {$in: ["$item.k", "$updatedFields"]
              }
            }
          },
          "as": "obj",
          "in": {
            "k": "$obj.k",
            "v": {$toString: "$obj.v"}
          }
        }
      }
    }
  },
  {
    $project: {
      oldDocument: {$arrayToObject: "$oldDocumentFilter"},
      newDocument: {$arrayToObject: "$newDocumentFilter"},
      _id: 0
    }
  }
])

如您在 Playground

You can use $objectToArray in order to format the keys as values, $filter them according to the updatedFields array and then use $arrayToObject to make them keys again.

Edit: using $map inside the filter to cast dates to strings, according to a request on the comments.

Something like this:

db.collection.aggregate([
  {
    $project: {
      oldDocumentArr: {$objectToArray: "$oldDocument"},
      newDocumentArr: {$objectToArray: "$newDocument"},
      updatedFields: 1
    }
  },
  {
    $project: {
      oldDocumentFilter: {
        $map: {
          input: {
            $filter: {
              input: "$oldDocumentArr",
              as: "item",
              cond: {$in: ["$item.k", "$updatedFields"]
              }
            }
          },
          "as": "obj",
          "in": {
            "k": "$obj.k",
            "v": {$toString: "$obj.v"}
          }
        }
      },
      newDocumentFilter: {
        $map: {
          input: {
            $filter: {
              input: "$newDocumentArr",
              as: "item",
              cond: {$in: ["$item.k", "$updatedFields"]
              }
            }
          },
          "as": "obj",
          "in": {
            "k": "$obj.k",
            "v": {$toString: "$obj.v"}
          }
        }
      }
    }
  },
  {
    $project: {
      oldDocument: {$arrayToObject: "$oldDocumentFilter"},
      newDocument: {$arrayToObject: "$newDocumentFilter"},
      _id: 0
    }
  }
])

As you can see on the playground

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文