当前位置: 首页 > 知识库问答 >
问题:

MongoDB对同一集合进行多次查找

邹祺
2023-03-14

我有两个集合比尔和员工。比尔包含有关每月学生账单的信息,员工包含在学校工作的所有类型的人(会计师、教师、维护等)。
比尔有billVerifyBy和classteacher字段,它们指向员工的记录。
账单收集

{
    "_id": ObjectId("ab12dns..."),  //mongoid
    "studentname": "demoUser",
    "class": { "section": "A"},
    "billVerifiedBy": "121212",
    "classteacher": "134239",

}

员工集合

json prettyprint-override">{
    "_id": ObjectId("121212"), // random number
    "name": "Darn Morphy",
    "department": "Accounts",
    "email": "dantest@test.com",
}

{
    "_id": ObjectId("134239"),
    "name": "Derreck",
    "department": "Faculty",
    "email": "derrect145@test.com",
}

我需要检索与特定账单相关的帐户和教师信息。我正在使用MongoDB查找来获取信息。但是,我必须查找同一个表两次,因为billVerifiedBy和classteacher属于相同的员工表,如下所示。

db.bill.aggregate([  
    {
        $lookup: {"from": "employee", "localField": "billVerifiedBy", "foreignField": "_id", "as": "accounts"}},
    },
    {
        $lookup: {"from": "employee", "localField": "classteacher", "foreignField": "_id", "as": "faculty"}},
    },
    {
        $project: {
            "studentname": 1, 
            "class": 1,
            "verifiedUser": "$accounts.name",
            "verifiedByEmail":"$accounts.email",
            "facultyName": "$faculty.name",
            "facultyEmail": "$faculty.email"
        }
    }
]

我不知道这是否是在单个员工集合中安排帐户和教员信息的好方法。在同一个集合中查找两次是正确的吗?或者我应该创建单独的帐户和教员集合并使用它进行查找。请建议在性能方面最好的方法。

共有1个答案

薛烨霖
2023-03-14

在mongoDB中,当您想从同一个集合中加入多个文档时,您可以使用“$lookup”及其“管道”和“let”选项。它使用定义的变量过滤您要获取的文档。

db.getCollection('Bill').aggregate([{
        "$lookup": {
            "as": "lookupUsers",
            "from": "Employee",
            // define variables that you need to use in pipeline to filter documents
            "let": {
                "verifier": "$billVerifiedBy",
                "teacher": "$classteacher"
            },
            "pipeline": [{ // filter employees who you need to filter.
                    "$match": {
                        "$expr": {
                            "$or": [{
                                    "$eq": ["$_id", "$$verifier"]
                                },
                                {
                                    "$eq": ["$_id", "$$teacher"]
                                }
                            ]
                        }
                    }
                },

                { // combine filtered 2 documents in an employee array
                    "$group": {
                        "_id": "",
                        "employee": {
                            "$addToSet": {
                                "_id": "$_id",
                                "name": "$name",
                                "department": "$department",
                                "email": "$email"
                            }
                        }
                    }
                },
                { // takes item from the array by predefined variable.
                    "$project": {
                        "_id": 0,
                        "billVerifiedBy": {
                            "$slice": [{
                                    "$filter": {
                                        "input": "$employee",
                                        "cond": {
                                            "$eq": ["$$this._id", "$$verifier"]
                                        }
                                    }
                                },
                                1
                            ]
                        },
                        "classteacher": {
                            "$slice": [{
                                    "$filter": {
                                        "input": "$employee",
                                        "cond": {
                                            "$eq": ["$$this._id", "$$teacher"]
                                        }
                                    }
                                },
                                1
                            ]
                        }
                    }
                },
                {
                    "$unwind": "$billVerifiedBy"
                },
                {
                    "$unwind": "$classteacher"
                },
            ]
        }
    },
    {
        "$unwind": "$lookupUsers"
    },
]);

输出如下:

{
    "_id": ObjectId("602916dcf4450742cdebe38d"),
    "studentname": "demoUser",
    "class": {
        "section": "A"
    },
    "billVerifiedBy": ObjectId("6029172e9ea6c9d4776517ce"),
    "classteacher": ObjectId("6029172e9ea6c9d4776517cf"),
    "lookupUsers": {
        "billVerifiedBy": {
            "_id": ObjectId("6029172e9ea6c9d4776517ce"),
            "name": "Darn Morphy",
            "department": "Accounts",
            "email": "dantest@test.com"
        },
        "classteacher": {
            "_id": ObjectId("6029172e9ea6c9d4776517cf"),
            "name": "Derreck",
            "department": "Faculty",
            "email": "derrect145@test.com"
        }
    }
}
 类似资料:
  • 我必须将属于多个实体的数据存储在一个集合中。但是当我查询然后返回时,我不希望结果中出现不需要的记录。我们如何使用Spring实现这一点?以下是我迄今为止所做的。 1.我在实体中给出相同的集合名称,如下所示。 2、我创建独立的mongoRepository接口 3.问题是 当我做animalRepo的时候。芬德尔或humanRepo。芬德尔,我收集了所有的记录。 4.我所期望的 AnimalRepo

  • 是否有一种内置方法可以将两个不同的聚合函数应用于同一列,而无需多次调用? 示例数据帧: 语法上错误,但直觉上正确的做法是: 显然,Python不允许重复的键。是否有其他方式来表达输入到?也许元组列表会更好地工作,以允许多个函数应用于同一列?但是似乎只接受字典。 除了定义一个只应用其中两个函数的辅助函数之外,还有其他解决方法吗?无论如何,这将如何与聚合工作?)

  • 我有一个名为“Prices”的MongoDB集合,我试图查询“startDate”和“endDate”之间的价格。 该集合每10秒存储一次价格,但是当查询此集合以绘制图形时,每1-2分钟的价格才是真正重要的。 我尝试用两种不同的方式编写此查询: 方法1:使用{$gte:startDate,$lte:endDate} 此方法引发以下错误: 如果删除排序('-timestamp')行,并再次运行此查询

  • 问题内容: 我将MongoDB与Node.JS结合使用。我有一个包含日期和其他行的集合。日期是一个JavaScript 对象。 如何按日期排序此收藏集? 问题答案: 只需对@JohnnyHK答案进行一些修改 在许多用例中,我们希望返回最新记录(例如最新更新/插入)。

  • 问题内容: 我们先前用于从集合中查找不同元素的实现过去是: 尝试将其升级到使用mongo 3.3.0+的当前实现是: 还尝试了 在这种情况下,迭代器的目标类型是什么? 问题答案: 您可以尝试这样的事情。

  • 我必须改进一个旧的服务,它对同一个服务进行多个连续调用,并将所有结果合并到一个列表中。 假设我们有一个ID列表=[1,2,3,…6],所以我必须用每个ID调用相同的API(带有改装和可观察)。 为此,我想使用Rx Android,但我对如何合并结果有疑问。 我们可以进行并行调用并按照相同的顺序合并结果吗? 为了提高时间响应,我们的想法是并行执行,但我不知道如何确保结果将按照与服务器调用相同的顺序进