gpt4 book ai didi

javascript - 基于多连接的MongoDB查询

转载 作者:行者123 更新时间:2023-11-30 15:10:34 25 4
gpt4 key购买 nike

关于联接和 MongoDB 有很多问题,但其中很多问题的答案已经过时,没有考虑 Mongo 3.x 之后的功能。我的问题是您将如何查询包含链接元素条件的表格?

这是一个极其简化的例子

const Person =  new mongoose.Schema({
gender: String
});

const Dog = new mongoose.Schema({
breed: String
});

const Team = new mongoose.Schema({
trainer: {
type: mongoose.Schema.ObjectId,
ref: 'Person'
},
members: [{
type: mongoose.Schema.ObjectId,
ref: 'Dog'
}]
})

想象一下,这已经在生产中并且不可能更改架构。

我如何检索所有至少有一只“ Poodle ”犬种成员并且训练师的性别是“男性”的团队?

最佳答案

以不同的方式提出您的问题:如何在 mongoDB 中加入两个以上的集合?

假设您的模型名称的集合名称是 dogsteamspeople(Mongoose 复数约定),以下是其中一种方法达到预期的结果:

Dog.aggregate([{
$match: {
breed: "Poodle"
}
},
{
$lookup: {
from: "teams",
localField: "_id",
foreignField: "members",
as: "team"
}
},
{
$unwind: "$team"
},
{
$lookup: {
from: "people",
localField: "team.trainer",
foreignField: "_id",
as: "trainer"
}
},

{
$unwind: "$trainer"
},

{
$match: {
"trainer.gender": "male"
}
},
{
$project: {
breed: 1,
trainer: 1,
team: {
_id: 1
}
}
}
], function(err, teams) {
console.log(teams)
});

在聚合管道中,我们执行以下操作:

  1. Dog为起点,匹配品种
  2. 然后使用$lookup将结果加入团队并获取那些包含成员引用“Poodle”的团队
  3. 2 的结果集包含团队数组(您可以删除 $lookup 下面的所有步骤以查看结果状态)。要将此数组拆分为另一个文档,我们使用 $unwind运算符(例如三个元素的团队将成为三个文档,所有文档的父字段都被复制)
  4. 在新的结果集上,再次应用 $lookup,这次是加入 people。这将人们置于训练器阵列中。
  5. 再次放松到split trainer
  6. 匹配trainer.gender "male"的结果集
  7. $project (选择)您需要的字段

最终的结果是这样的:

{
"_id" : ObjectId("596e5500b5174986059958a8"),
"breed" : "Poodle",
"team" : {
"_id" : ObjectId("596e564fb5174986059958de")
},
"trainer" : {
"_id" : ObjectId("596e54bfb51749860599589c"),
"gender" : "male"
}
}


{
"_id" : ObjectId("596e5500b5174986059958a8"),
"breed" : "Poodle",
"team" : {
"_id" : ObjectId("596e564fb5174986059958e6")
},
"trainer" : {
"_id" : ObjectId("596e54bfb51749860599589c"),
"gender" : "male"
}
}


{
"_id" : ObjectId("596e5500b5174986059958b2"),
"breed" : "Poodle",
"team" : {
"_id" : ObjectId("596e564fb5174986059958de")
},
"trainer" : {
"_id" : ObjectId("596e54bfb51749860599589c"),
"gender" : "male"
}
}


{
"_id" : ObjectId("596e5500b5174986059958b2"),
"breed" : "Poodle",
"team" : {
"_id" : ObjectId("596e564fb5174986059958e6")
},
"trainer" : {
"_id" : ObjectId("596e54bfb51749860599589c"),
"gender" : "male"
}
}

本质上,我们已经搜索了 Dog 并在此过程中加入并匹配了更多的集合。最终文档中的根 _id 是狗的 _id 而不是团队,因此从技术上讲,结果集包含包含团队和训练员的狗,但您可以将它们视为“团队”文档。您可以反过来,从 Person 开始到 Dog

此外,结果的结构也不完美。您可能需要一个结构良好的格式,因为人口确实喜欢包含嵌入式 trainermembersteams。通过聚合管道中的一些调整,我确信可以实现结构良好的结构。

最后,这与另一个答案中建议的 Mongoose 种群不同。主要区别在于,在这种情况下,您已将查找所需文档的任务委派给 mongo 服务器,而且显然是一次性完成的。在人口中,同样需要太多的客户端处理和对数据库的许多请求。但是$lookup适用于未分片的集合,在这种情况下您可能更喜欢人口或考虑 this回答。

关于javascript - 基于多连接的MongoDB查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45174315/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com