更改 mongoDB 聚合中的字段类型,$lookup 是否在字段上使用索引?
Change type of field inside mongoDB aggregation and does $lookup utilises index on fields or not?
我正在使用 $lookup 在 mongodb 中执行连接,现在我遇到了一个问题。
我有两个 collections,第一个包含用户的所有书签 b运行ds,第二个包含有关 brands.Now 的所有详细信息,我正在尝试 return 所有 b运行ds 详细信息已被用户收藏。
user_bookmarked Collection
{"mobile_no": "8971740148", "brands": ["5829c1df334d40e20e1d1c19", "5829c1df334d40e20e1d1c20", "5829c1df334d40e20e1d1c21"]}
b运行ds Collection
{"_id": ObjectId("5829c1df334d40e20e1d1c19"), "brand_name": "Versace"}
{"_id": ObjectId("5829c1df334d40e20e1d1c20"), "brand_name": "Lee Cooper"}
{"_id": ObjectId("5829c1df334d40e20e1d1c21"), "brand_name": "Levis"}
我的聚合管道代码如下
{ $match: { mobile_no: mobile_no }},
{ $unwind: { path: "$brands", includeArrayIndex: "brandsposition"}},
{ $lookup: {from: "brands",localField: "brands",foreignField: "_id",as: "user_bookmarks"}},
现在我面临的问题是上面的代码没有 return 任何东西,因为我将 b运行ds id 作为字符串存储在我的 user_bookmarked collection 中但不是 ObjectId,所以没有 returned。现在谁能告诉我如何更改聚合查询中的字段类型。
我想问的第二件事请告诉我在使用 $lookup 时 mongodb 是否利用 foreign_field 上的索引。因为我 运行 在聚合管道上方 explain: true 但是我没有找到上面查询使用的任何索引我得到了这个 return 输出.
db.user_bookmarked.runCommand('aggregate', {pipeline: [{ $match: { mobile_no: mobile_no }},
{ $unwind: { path: "$brands", includeArrayIndex: "brandsposition"}},
{ $lookup: {from: "brands",localField: "brands",foreignField: "_id",as: "user_bookmarks"}}], explain: true})
{
"waitedMS" : NumberLong(0),
"stages" : [
{
"$cursor" : {
"query" : {
"mobile_no" : "8971740148"
},
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.restaurants",
"indexFilterSet" : false,
"parsedQuery" : {
"mobile_no" : {
"$eq" : "8971740148"
}
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"mobile_no" : {
"$eq" : "8971740148"
}
},
"direction" : "forward"
},
"rejectedPlans" : [ ]
}
}
},
{
"$unwind" : {
"path" : "$brands",
"includeArrayIndex" : "brandsposition"
}
},
{
"$lookup" : {
"from" : "brands",
"as" : "user_bookmarks",
"localField" : "brands",
"foreignField" : "_id"
}
}
],
"ok" : 1
}
现在谁能帮我离开这里我已经搜索了这两个东西,即如何更改聚合中的字段类型以及 $lookup 是否使用索引但没有找到任何有用的东西请帮助我离开伙计们,这真的很可观。
您不能将字符串转换为管道中的对象 ID,您必须遍历每个文档并手动转换它,使用类似的东西(无论如何您不应该存储类型的混合匹配,所以它可能是值得长期更新运行):
how to convert string to numerical values in mongodb
至于 $lookup 是否使用索引,如果您查看此博客中的统计信息,您会看到使用了索引 -
http://guyharrison.squarespace.com/blog/2016/7/4/join-performance-in-mongodb-32-using-lookup.html
尝试在人口之前将您的品牌投射到 ObjectId:
user_bookmarked.brands.map((brand) => return mongoose.Types.ObjectId(brand) )
但您真的应该考虑将它们存储为 refs,您的模型应该类似于:
const user_bookmarked = new mongoose.Schema({
...
brands: [{type: mongoose.Schema.Types.ObjectId, ref: 'Brands'}],
...
})
这样一开始它们就是 ObjectId。!
关于第二个问题,这个post解释了我认为:join-performance-in-mongodb-32-using-lookup
我正在使用 $lookup 在 mongodb 中执行连接,现在我遇到了一个问题。 我有两个 collections,第一个包含用户的所有书签 b运行ds,第二个包含有关 brands.Now 的所有详细信息,我正在尝试 return 所有 b运行ds 详细信息已被用户收藏。
user_bookmarked Collection
{"mobile_no": "8971740148", "brands": ["5829c1df334d40e20e1d1c19", "5829c1df334d40e20e1d1c20", "5829c1df334d40e20e1d1c21"]}
b运行ds Collection
{"_id": ObjectId("5829c1df334d40e20e1d1c19"), "brand_name": "Versace"}
{"_id": ObjectId("5829c1df334d40e20e1d1c20"), "brand_name": "Lee Cooper"}
{"_id": ObjectId("5829c1df334d40e20e1d1c21"), "brand_name": "Levis"}
我的聚合管道代码如下
{ $match: { mobile_no: mobile_no }},
{ $unwind: { path: "$brands", includeArrayIndex: "brandsposition"}},
{ $lookup: {from: "brands",localField: "brands",foreignField: "_id",as: "user_bookmarks"}},
现在我面临的问题是上面的代码没有 return 任何东西,因为我将 b运行ds id 作为字符串存储在我的 user_bookmarked collection 中但不是 ObjectId,所以没有 returned。现在谁能告诉我如何更改聚合查询中的字段类型。
我想问的第二件事请告诉我在使用 $lookup 时 mongodb 是否利用 foreign_field 上的索引。因为我 运行 在聚合管道上方 explain: true 但是我没有找到上面查询使用的任何索引我得到了这个 return 输出.
db.user_bookmarked.runCommand('aggregate', {pipeline: [{ $match: { mobile_no: mobile_no }},
{ $unwind: { path: "$brands", includeArrayIndex: "brandsposition"}},
{ $lookup: {from: "brands",localField: "brands",foreignField: "_id",as: "user_bookmarks"}}], explain: true})
{
"waitedMS" : NumberLong(0),
"stages" : [
{
"$cursor" : {
"query" : {
"mobile_no" : "8971740148"
},
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.restaurants",
"indexFilterSet" : false,
"parsedQuery" : {
"mobile_no" : {
"$eq" : "8971740148"
}
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"mobile_no" : {
"$eq" : "8971740148"
}
},
"direction" : "forward"
},
"rejectedPlans" : [ ]
}
}
},
{
"$unwind" : {
"path" : "$brands",
"includeArrayIndex" : "brandsposition"
}
},
{
"$lookup" : {
"from" : "brands",
"as" : "user_bookmarks",
"localField" : "brands",
"foreignField" : "_id"
}
}
],
"ok" : 1
}
现在谁能帮我离开这里我已经搜索了这两个东西,即如何更改聚合中的字段类型以及 $lookup 是否使用索引但没有找到任何有用的东西请帮助我离开伙计们,这真的很可观。
您不能将字符串转换为管道中的对象 ID,您必须遍历每个文档并手动转换它,使用类似的东西(无论如何您不应该存储类型的混合匹配,所以它可能是值得长期更新运行):
how to convert string to numerical values in mongodb
至于 $lookup 是否使用索引,如果您查看此博客中的统计信息,您会看到使用了索引 -
http://guyharrison.squarespace.com/blog/2016/7/4/join-performance-in-mongodb-32-using-lookup.html
尝试在人口之前将您的品牌投射到 ObjectId:
user_bookmarked.brands.map((brand) => return mongoose.Types.ObjectId(brand) )
但您真的应该考虑将它们存储为 refs,您的模型应该类似于:
const user_bookmarked = new mongoose.Schema({
...
brands: [{type: mongoose.Schema.Types.ObjectId, ref: 'Brands'}],
...
})
这样一开始它们就是 ObjectId。!
关于第二个问题,这个post解释了我认为:join-performance-in-mongodb-32-using-lookup