【问题标题】:MongoDB aggregate field in array of objects对象数组中的 MongoDB 聚合字段
【发布时间】:2019-02-19 14:20:39
【问题描述】:

我正在尝试解决一个问题一段时间,但不幸的是没有运气。 所以我正在重构一些旧代码(它使用了众所周知的 get each doc 查询并对其进行 for 循环),并且我正在尝试聚合结果以删除 BE 正在进行的数千次调用。

当前的文档是这样的

{
    "_id" : ObjectId("5c176fc65f543200019f8d66"),
    "category" : "New client",
    "description" : "",
    "createdById" : ObjectId("5c0a858da9c0f000018382bb"),
    "createdAt" : ISODate("2018-12-17T09:43:34.642Z"),
    "sentAt" : ISODate("2018-12-17T09:44:25.902Z"),
    "scheduleToBeSentAt" : ISODate("2018-01-17T11:43:00.000Z"),
    "recipients" : [ 
        {
            "user" : ObjectId("5c0a858da9c0f000018382b5"),
            "status" : {
                "approved" : true,
                "lastUpdated" : ISODate("2018-01-17T11:43:00.000Z")
            }
        }, 
        {
            "user" : ObjectId("5c0a858da9c0f000018382b6"),
            "status" : {
                "approved" : true,
                "lastUpdated" : ISODate("2018-01-17T11:43:00.000Z")
            }
        }, 
    ],
    "recipientsGroup" : "All",
    "isActive" : false,
    "notificationSent" : true
}

recipients.user 字段是 Users 集合中用户的 objectID。 修改它的正确方法是什么,结果将是

{
    "_id": ObjectId("5c176fc65f543200019f8d66"),
    "category": "New client",
    "description": "",
    "createdById": ObjectId("5c0a858da9c0f000018382bb"),
    "createdAt": ISODate("2018-12-17T09:43:34.642Z"),
    "sentAt": ISODate("2018-12-17T09:44:25.902Z"),
    "scheduleToBeSentAt": ISODate("2018-01-17T11:43:00.000Z"),
    "recipients": [{
            "user": {
                "_id": ObjectId("5c0a858da9c0f000018382b5"),
                "title": "",
                "firstName": "Monique",
                "lastName": "Heinrich",
                "qualification": "Management",
                "isActive": true
            },
            "status": {
                "approved": true,
                "lastUpdated": ISODate("2018-01-17T11:43:00.000Z")
            }
        },
        {
            "user": {
                "_id": ObjectId("5c0a858da9c0f000018382b6"),
                "title": "",
                "firstName": "Marek",
                "lastName": "Pucelik",
                "qualification": "Management",
                "isActive": true
            },
            "status": {
                "approved": true,
                "lastUpdated": ISODate("2018-01-17T11:43:00.000Z")
            }
        },
    ],
    "recipientsGroup": "All",
    "isActive": false,
    "notificationSent": true
}

聚合是一个强大的工具,但有时简单的解决方案会让你的大脑受伤.....

我尝试过这样的事情,但也没有运气。

db.getCollection('Protocols').aggregate([
{
    $lookup: {
        from: "Users",
        localField: "recipients.user",
        foreignField: "_id",
        as: "users"
    }
},
{
    $project: {
        "recipients": {
            "status": 1,
            "user": {
                $filter: {
                input: "$users",
                cond: { $eq: ["$$this._id", "$user"] }
                }
            },
        }
    }
}
])

【问题讨论】:

  • stackoverflow.com/questions/46323106/… 如果我理解你的问题
  • 在本例中,结果是从原始 DOC 中过滤出来的。我需要用过滤聚合数组结果中的值替换结果对象数组中的字段
  • 这正是我在那里所做的。过滤后的结果会覆盖原始值。您可以在此处进行更广泛的解释:devsbedevin.net/…

标签: mongodb aggregate


【解决方案1】:

您可以在聚合管道中使用$lookup 运算符

https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/

但出于性能原因,您宁愿在 recipents 数组中复制用户对象以避免此类复杂查询。

【讨论】:

    猜你喜欢
    • 2021-06-21
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    • 1970-01-01
    • 1970-01-01
    • 2020-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多