MongoDB 获取数组值匹配的所有文档

标签 mongodb

我有以下文档结构:

  {
    "input": {
      "fields": [
        {
          "name": "last_name_hebrew",
          "text": "test1",
        },
      ],
    },
    "output": {
      "fields": [
        {
          "name": "last_name_hebrew",
          "text": "test1"
        },
      ],
    },
  },

我想获取所有文档,其中字段具有名称为 last_name_hebrew 的对象与 text 一样output.fields 的值(value).

例如在给定的结构中它会返回这个文件因为input.fields.namelast_name_hebrewtext等于 textoutput .

注意我不能保证 fields input 中的数组或 output会有name: last_name_hebrew在数组中。

我该怎么做?

这是我尝试首先强制数组具有 name 的文档的 last_name_hebrew :

db.collection.find({
  "input.fields": {
    $elemMatch: {
      "name": "last_name_hebrew"
    }
  },
  "output.fields": {
    $elemMatch: {
      "name": "last_name_hebrew"
    }
  },
  
})

但现在我需要比较 text值(value)观。

最佳答案

  • $elemMatch 的前两个条件是正确的
  • 添加表达式匹配,首先使用 $filterinput 中找到具有 last_name_hebrew 名称的匹配元素,并从该过滤结果中获取第一个元素使用 $arrayElemAtoutput 字段的过程相同,然后使用 $eq
  • 匹配两个对象
db.collection.find({
  "input.fields": { $elemMatch: { "name": "last_name_hebrew" } },
  "output.fields": { $elemMatch: { "name": "last_name_hebrew" } },
  $expr: {
    $eq: [
      {
        $arrayElemAt: [
          {
            $filter: {
              input: "$input.fields",
              cond: { $eq: ["$$this.name", "last_name_hebrew"] }
            }
          },
          0
        ]
      },
      {
        $arrayElemAt: [
          {
            $filter: {
              input: "$output.fields",
              cond: { $eq: ["$$this.name", "last_name_hebrew"] }
            }
          },
          0
        ]
      }
    ]
  }
});

Playground


第二个选项:如果你想更具体地匹配精确的 2 个字段 nametext 都只需要添加 $let运算符从过滤器返回字段,

db.collection.find({
  "input.fields": { $elemMatch: { "name": "last_name_hebrew" } },
  "output.fields": { $elemMatch: { "name": "last_name_hebrew" } },
  $expr: {
    $eq: [
      {
        $let: {
          vars: {
            input: {
              $arrayElemAt: [
                {
                  $filter: {
                    input: "$input.fields",
                    cond: { $eq: ["$$this.name", "last_name_hebrew"] }
                  }
                },
                0
              ]
            }
          },
          in: { name: "$$input.name", text: "$$input.text" }
        }
      },
      {
        $let: {
          vars: {
            output: {
              $arrayElemAt: [
                {
                  $filter: {
                    input: "$output.fields",
                    cond: { $eq: ["$$this.name", "last_name_hebrew"] }
                  }
                },
                0
              ]
            }
          },
          in: { name: "$$output.name", text: "$$output.text" }
        }
      }
    ]
  }
})

Playground


第三个选项:为了更具体地检查循环中的两个字段,

  • 首先使用 $filter 在输入字段中按名称过滤匹配的元素
  • 将上述过滤器结果传递给另一个过滤器
  • 过滤匹配输出字段中的名称和文本字段,如果不为[]空则返回过滤结果
  • $ne 检查返回结果是否为[]空
db.collection.find({
  "input.fields": { $elemMatch: { "name": "last_name_hebrew" } },
  "output.fields": { $elemMatch: { "name": "last_name_hebrew" } },
  $expr: {
    $ne: [
      {
        $filter: {
          input: {
            $filter: {
              input: "$input.fields",
              cond: { $eq: ["$$this.name", "last_name_hebrew"] }
            }
          },
          as: "i",
          cond: {
            $ne: [
              {
                $filter: {
                  input: "$output.fields",
                  cond: {
                    $and: [
                      { $eq: ["$$this.name", "$$i.name"] },
                      { $eq: ["$$this.text", "$$i.text"] }
                    ]
                  }
                }
              },
              []
            ]
          }
        }
      },
      []
    ]
  }
})

Playground

关于MongoDB 获取数组值匹配的所有文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66801727/

相关文章:

ios - ISO8601 格式在 MongoDB 和 iOS 中不同

mongodb 日志我可以清空这个文件吗?

mongodb - 删除嵌套在 MongoDB 数组中的子文档

node.js - MEAN 堆栈组件如何组合在一起?

mongodb - $group 在 mongodb 中嵌套数组

node.js - Nodejs Mongodb更新多个集合

javascript - 在单个内部属性上查找匹配的数组内容和长度

node.js - mongodb TypeError : client. db.collection 不是函数

Mongodb 3.4 - 将副本添加到副本集的正确方法是什么?

c# - 诊断应用程序变慢和内存消耗(可能是 WCF 或 MongoDB C# 驱动程序)?