如果我有client个和task个Collection

task

{
    fields: {
        client: [
            {
                uuid: 'b5050bf2-ca75-4b0a-920c-628ca45f929a',
            }
        ],
        uuid: '35c0541d-dd39-420b-9f74-027a9a268f88',
    }
}

client

{
    updated_at: ISODate('2024-03-18T12:07:17.313Z'),
    fields: {
        uuid: 'b5050bf2-ca75-4b0a-920c-628ca45f929a',
    }
}

如何列出所有任务与他们的最新客户?我有代码,但它不返回客户端数据在related_client field

list_of_conditions = [
        {'$sort': {'updated_at': pymongo.DESCENDING}},
        {'$group': {'_id': '$fields.uuid', 'doc': {'$first': '$$ROOT'}}},
        {'$replaceRoot': {'newRoot': '$doc'}},
        {'$match':
            {
                'fields.uuid': {'$in': list(tasks_uuids)},
            },
            },
        {'$lookup':
            {
                'from': 'client',
                'let': {'client_uuid': '$fields.uuid'},
                'pipeline': [
                    {'$match': {'$expr': {'$eq': ['$fields.client.uuid', '$$client_uuid']}}},
                    {'$sort': {'updated_at': -1}},
                    {'$limit': 1}
                ],
                'as': 'related_client',
            },
        },
    ]
collection = await mongo_uow.task_actions.get_db_collection()  # task collection
collection_objects = collection.aggregate(list_of_conditions)

推荐答案

  1. 你在client上的查找有"client_uuid": "$fields.uuid",但它应该是$fields.client.uuid

    • 当你执行let时,它仍然是指你运行聚合的base collection中的字段,所以是task.
  2. 在查找的$match部分中,您是client集合中的in,因此{'$expr': {'$eq': ['$fields.client.uuid', '$$client_uuid']}}应该是$fields.uuid.

    • 你在let&lookup指数中颠倒了你试图引用的领域,这就是为什么它不匹配的原因.
  3. task集合中,"$fields.client.uuid"是一个数组,所以你不能为"uuid array—of—uuid"进行相等匹配.&使用$in操作员.

  4. 顺便说一句,你的第一阶段是{'$sort': {'updated_at': pymongo.DESCENDING}},但任务中没有update_at字段,只有在"客户端"中.

使用注释1到3的修复,并忽略第一排序阶段,查找应该是:

db.task.aggregate([
  { "$sort": { "updated_at": -1 } },
  {
    "$group": {
      "_id": "$fields.uuid",
      "doc": { "$first": "$$ROOT" }
    }
  },
  { "$replaceRoot": { "newRoot": "$doc" } },
  {
    "$match": {
      "fields.uuid": {
        // this is hard-coded here, to have a working example
        "$in": [ "35c0541d-dd39-420b-9f74-027a9a268f88" ]
      }
    }
  },
  {
    "$lookup": {
      "from": "client",
      "let": {
        "client_uuid": "$fields.client.uuid"  // fixed
      },
      "pipeline": [
        {
          "$match": {
            "$expr": {
              "$in": [  // fixed
                "$fields.uuid",  // fixed
                "$$client_uuid"
              ]
            }
          }
        },
        { "$sort": { "updated_at": -1 } },
        { "$limit": 1 }
      ],
      "as": "related_client"
    }
  }
])

Mongo Playground

结果:

[
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "fields": {
      "client": [
        {
          "uuid": "b5050bf2-ca75-4b0a-920c-628ca45f929a"
        }
      ],
      "uuid": "35c0541d-dd39-420b-9f74-027a9a268f88"
    },
    "related_client": [
      {
        "_id": ObjectId("5a934e000102030405000000"),
        "fields": {
          "uuid": "b5050bf2-ca75-4b0a-920c-628ca45f929a"
        },
        "updated_at": ISODate("2024-03-18T12:07:17.313Z")
      }
    ]
  }
]

下面是您的Python代码中的probably:

list_of_conditions = [
        {'$sort': {'updated_at': pymongo.DESCENDING}},
        {'$group': {'_id': '$fields.uuid', 'doc': {'$first': '$$ROOT'}}},
        {'$replaceRoot': {'newRoot': '$doc'}},
        {'$match':
            {
                'fields.uuid': {'$in': list(tasks_uuids)},
            },
        },
        {'$lookup':
            {
                'from': 'client',
                'let': {'client_uuid': '$fields.client.uuid'},
                'pipeline': [
                    {"$match": {
                        "$expr": {
                            "$in": ["$fields.uuid", "$$client_uuid"]
                        }
                    }},
                    {'$sort': {'updated_at': -1}},
                    {'$limit': 1}
                ],
                'as': 'related_client',
            },
        },
    ]

Mongodb相关问答推荐

MongoDB 4.4如何使用未知密钥更新dict

Mongodb如果数组中有外部键,则将排序应用到查找结果

如何限制/筛选子文档中的条目?

Go mongo-驱动程序测试,FindOne未根据给定的筛选器返回正确结果

为什么我的Mongoose更新找不到匹配?

执行聚合以消除重复并获得唯一计数

MongoDB 对特定搜索查询的响应时间较长

Mongo 将一个数组链接到另一个数组

MongoDB 聚合 - 条件 $lookup 取决于字段是否存在

如何修改 mongodb 中嵌套对象数组中的字段名称/键?

是否可以迭代 mongo 游标两次?

如何在 Mongo 聚合中合并文档中的数组字段

如何在mongo中插入带有日期的文档?

什么是 mongodb 中的admin数据库?

MongoError:Topology is closed, please connect despite established database connection

文本的 MongoID 数据类型

用于嵌入式集合的 MongoDB 首选模式.文档与数组

mongodb 的计数性能

如何使用服务器实例指定 mongodb 用户名和密码?

使用 $in 进行不区分大小写的搜索