首页 > 解决方案 > 查询 MongoDB 嵌套文档并找到完全匹配的内部对象,其中一个过滤器将其自己的字段值作为条件

问题描述

我在 Mongo 集合中有以下文档。

{
   "_id":"112211",
   "student":{
      "student_display_name":"Siva",
      "first_name":"Siva",
      "last_name":"Ram",
      "age":"20",
      "department":"IT",
      "section":"D",
      "edit_sequence":"2",
      "unique_id":"siva_2",
      "address":{
         "data":[
            {
               "student_display_name":"Siva",
               "first_name":"Siva",
               "last_name":"Ram",
               "student_id":"siva_2",
               "street":"Perter's Park",
               "area":"BMS Road",
               "pincode":"560001"
            },
            {
               "student_display_name":"Siva",
               "first_name":"Siva",
               "last_name":"Ram",
               "student_id":"siva_1",
               "street":"St.Mary's Colony",
               "area":"BMS Road",
               "pincode":"560001"
            },
            {
               "student_display_name":"Siva",
               "first_name":"Siva",
               "last_name":"Ram",
               "student_id":"siva_0",
               "street":"MG Colony",
               "area":"BMS Road",
               "pincode":"560001"
            }
         ]
      },
      "student":{
         "data":[
            {
               "student_display_name":"Siva",
               "first_name":"Siva",
               "last_name":"Ram",
               "age":"20",
               "department":"IT",
               "section":"B",
               "edit_sequence":"1",
               "unique_id":"siva_1"
            },
            {
               "student_display_name":"Siva",
               "first_name":"Siva",
               "last_name":"Ram",
               "age":"20",
               "department":"IT",
               "section":"A",
               "edit_sequence":"0",
               "unique_id":"siva_0"
            }
         ]
      }
   },
   "college":"student college",
   "root_table":"student"
}

在本文档中,我需要使用以下匹配过滤器进行查询。

{
   "$match":{
      "$or":[
         {
            "student.address.data.pincode":"560001"
         },
         {
            "$and":[
               {
                  "student.address.data.data.last_name":"Siva"
               },
               {
                  "student.address.data.data.first_name":"Ram"
               }
            ]
         }
      ]
   }
}

使用这些匹配过滤器,我们将获得address.data数组下的所有 3 个对象。但是,从这些结果中,我想根据“ student.unique_id like student.address.data.student_id = student.unique_id ”值进一步过滤,这样我只会得到一个匹配,如下所示。

这是我想要的最终结果。

 {
       "address":{
                   "student_display_name":"Siva",
                   "first_name":"Siva",
                   "last_name":"Ram",
                   "student_id":"siva_2",
                   "street":"Perter's Park",
                   "area":"BMS Road",
                   "pincode":"560001"
                }
    }

如何在 MongoDB 中实现这一点?

标签: mongodbmongodb-queryaggregation-framework

解决方案


注意:如果您student.address.data只包含相同的学生数据,您可以在第二阶段省略两次过滤。

文档:$reduce

伪代码

reduce(input, initial={student_id: '${student.unique_id}'}, condition)
    value = initial
    for this in input:
        if this.pincode == '...'
           AND this.last_name == '...'
           AND this.first_name == '...'
           AND this.student_id == value.student_id:
           value = this
        else:
           value = value
    return value

试试这个:

db.student.aggregate([
  {
    $match: {
      "$and": [
        {
          "student.address.data.pincode": "560001"
        },
        {
          "student.address.data.last_name": "Ram"
        },
        {
          "student.address.data.first_name": "Siva"
        }
      ]
    }
  },
  {
    $project: {
      _id: 0,
      "address": {
        $reduce: {
          input: "$student.address.data",
          initialValue: {
            student_id: "$student.unique_id"
          },
          in: {
            $cond: [
              {
                $and: [
                  {
                    $eq: [ "$$this.pincode", "560001" ]
                  },
                  {
                    $eq: [ "$$this.first_name", "Siva" ]
                  },
                  {
                    $eq: [ "$$this.last_name", "Ram" ]
                  },
                  {
                    $eq: [ "$$value.student_id", "$$this.student_id" ]
                  }
                ]
              },
              "$$this",
              "$$value"
            ]
          }
        }
      }
    }
  }
])

Mongo游乐场


推荐阅读