$ filter在mongodb中最多达到2个嵌套级别

时间:2018-07-13 17:17:25

标签: mongodb nosql aggregation-framework

我有一个这样的数据库:

{
  "Hospitais": [
    {
      "utis": [
        {
          "_id": 893910,
          "nome": "UTI1",
          "leitos": [
            {
              "_id": 128938120,
              "_paciente": "Oliver"
            },
            {
              "_id": 12803918239,
              "_paciente": "Priscilla"
            }
          ]
        },
        {
          "_id": 38471839,
          "nome": "UTI2",
          "leitos": [
            {
              "_id": 48102938109,
              "_paciente": "Serveró"
            },
            {
              "_id": 501293890,
              "_paciente": "Thales"
            }
          ]
        },
        {
          "_id": 58109238190,
          "nome": "UTI3",
          "leitos": [
            {
              "_id": 93801293890,
              "_paciente": "Lucia"
            },
            {
              "_id": 571029390,
              "_paciente": "Amanda"
            }
          ]
        }
      ],
      "nome": "Dorio Silva"
    },
    {
      "utis": [
        {
          "_id": 410923810,
          "nome": "UTI1",
          "leitos": [
            {
              "_id": 48102938190,
              "_paciente": "Neymar"
            },
            {
              "_id": 48102938190,
              "_paciente": "Thiago"
            }
          ]
        },
        {
          "_id": 41092381029,
          "nome": "UTI2",
          "leitos": [
            {
              "_id": 10293182309,
              "_paciente": "Brazza"
            },
            {
              "_id": 38190238,
              "_paciente": "Pelé"
            }
          ]
        },
        {
          "_id": 83102938109,
          "nome": "UTI3",
          "leitos": [
            {
              "_id": 810923810,
              "_paciente": "Aparecida"
            },
            {
              "_id": 20938904209,
              "_paciente": "Pimentinha"
            }
          ]
        }
      ],
      "nome": "Apart Hospital"
    }
]
}

我只需要返回与输入“ Hospitais.nome”匹配的医院数组,并且在医院数组的每个数组中都有一个名为“ utis”的数组,我也想将其过滤在一起, 以下是“预期结果”

我已经通过许多不同的方式尝试过此方法,而我最近尝试过的方法是此代码:

db.collection.aggregate(
[
    { "$match": { "Hospitais.nome": 'Dorio Silva'} },
    {
        "$project": {
            _id: 0,
            Hospitais: {
                $filter: {
                    input: "$Hospitais",
                    as: "hospital",
                    cond: { $and: [{$eq: ["$$hospital.nome", 'Dorio Silva']},{ $eq: ["$$hospital.utis.nome",'UTI1']}]}
                }
            }
        }
    }
]

);

据我对聚合过滤器的了解,它只应显示Hospital.nome为“ Dorio Silva”的Hospitais数组的对象和Hospital.utis.nome为“ UTI1”的Hospital.utis的对象

我期望的是

[
	{
		"utis" : [
			{
				"_id" : NumberInt("893910"),
				"nome" : "UTI1",
				"leitos" : [
					{
						"_id" : NumberInt("128938120"),
						"_paciente" : "Oliver"
					},
					{
						"_id" : NumberLong("12803918239"),
						"_paciente" : "Priscilla"
					}
				]
			}
		],
		"nome" : "Dorio Silva"
	}
]

但是那绝不是结果,我可以按要求发布结果,但是我认为可能不需要。 查询结果的正确方法是什么?我建立数据库的方式有什么问题吗?可以做得更好吗?

1 个答案:

答案 0 :(得分:1)

您需要$unwind第一个数组,然后可以轻松地将$filter应用到嵌套数组

db.collection.aggregate([
  { "$unwind": "$Hospitais" },
  { "$match": { "Hospitais.nome": "Dorio Silva" } },
  { "$project": {
    "Hospitais": {
      "$filter": {
        "input": "$Hospitais.utis",
        "as": "uti",
        "cond": {
          "$eq": ["$$uti.nome", "UTI1"]
        }
      }
    }
  }}
])

或者您也可以尝试

db.collection.aggregate([
  { "$match": { "Hospitais.nome": "Dorio Silva" } },
  { "$project": {
    "Hospitais": {
      "$filter": {
        "input": {
          "$map": {
            "input": "$Hospitais",
            "as": "hospital",
            "in": {
              "nome": "$$hospital.nome",
              "utis": {
                "$filter": {
                  "input": "$$hospital.utis",
                  "as": "uti",
                  "cond": {
                    "$eq": ["$$uti.nome", "UTI1"]
                  }
                }
              }
            }
          }
        },
        "as": "hospital",
        "cond": {
          "$eq": ["$$hospital.nome", "Dorio Silva"]
        }
      }
    }
  }}
])

两者都会给出相似的输出

[
  {
    "Hospitais": [
      {
        "_id": 893910,
        "leitos": [
          {
            "_id": 1.2893812e+08,
            "_paciente": "Oliver"
          },
          {
            "_id": 1.2803918239e+10,
            "_paciente": "Priscilla"
          }
        ],
        "nome": "UTI1"
      }
    ]
  }
]