查找管道中的MongoDB elemMatch?

2024-06-17 08:46:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个引用另一个文档的文档,我希望加入这些文档并根据子文档中数组的内容进行筛选:

部署计算机文档:

{
  "_id": 1,
  "name": "Test Machine",
  "machine_status": 10, 
  "active": true
}

机器状态文件:

{
  "_id": 10,
  "breakdown": [
    {
      "status_name": "Rollout",
      "state": "complete"
    },
    {
      "status_name": "Deploying",
      "state": "complete"
    }
  ]
}

我使用的是Mongo 3.6,在查找和管道方面取得了混合成功,下面是我在python MongoEngine中使用的对象,它被传递给聚合函数:

pipeline = [
    {'$match': {'breakdown': {'$elemMatch': {'status_name': 'Rollout'}}}},
    {'$lookup':
        {
            'from': 'deployment_machine',
            'let': {'status_id': '$_id'},
            'pipeline': [
                {'$match':
                    {'$expr':
                        {'$and': [
                            {'$eq': ['$machine_status', '$$status_id']},
                        ]},
                    }
                }
            ],
            'as': 'result',

        },
    },
    {'$project': {
        'breakdown': {'$filter': {
            'input': '$breakdown',
            'as': 'breakdown',
            'cond': {'$eq': ['$$breakdown.status_name', 'Rollout']}            
        }}
    }},
]

result = list(MachineStatus.objects.aggregate(*pipeline))

这很好,但如何排除部署计算机未处于活动状态的结果?我觉得它必须在项目中,但找不到一个有效的条件。谢谢你的帮助


Tags: name文档idpipeline部署asmatchstatus
2条回答

您可以在$lookup管道中添加更多条件

pipeline = [
  { $match: { breakdown: { $elemMatch: { status_name: "Rollout" } } } },
  {
    $lookup: {
      from: "deployment_machine",
      let: { status_id: "$_id" },
      pipeline: [
        {
          $match: {
            $expr: { $eq: ["$machine_status", "$$status_id"] },
            active: false
          }
        }
      ],
      as: "result",
    }
  },
  {
    $project: {
      breakdown: {
        $filter: {
          input: "$breakdown",
          as: "breakdown",
          cond: { $eq: ["$$breakdown.status_name", "Rollout"] },
        }
      }
    }
  }
];

相关问题 更多 >