如何在mongoDB中创建从两个集合读取的视图?
从mongoDB语法开始,并在项目中使用。 我正在寻找一个解决方案,我可以结合两个以上的集合与夫妇的条件,以创建一个视图 这是我的收藏范围如何在mongoDB中创建从两个集合读取的视图?,mongodb,aggregation-framework,Mongodb,Aggregation Framework,从mongoDB语法开始,并在项目中使用。 我正在寻找一个解决方案,我可以结合两个以上的集合与夫妇的条件,以创建一个视图 这是我的收藏范围 /* 1 */ { "_id" : ObjectId("1"), "range" : { "start" : "00" }, "products" : [ { "id" : "01",
/* 1 */
{
"_id" : ObjectId("1"),
"range" : {
"start" : "00"
},
"products" : [
{
"id" : "01",
"name" : "FirstProduct",
"type" : "First Type"
},
{
"id" : "02",
"name" : "Second Product",
"type" : "Second Type"
},
{
"id" : "03",
"name" : "Third Product",
"type" : "Third Type"
},
]
}
/* 2 */
{
"_id" : ObjectId("2"),
"range" : {
"start" : "100",
},
"products" : [
{
"id" : "01",
"name" : "First Product",
"type" : "First Type"
},
{
"id" : "02",
"name" : "Second Product",
"type" : "Second Type"
}
]
}
/* 3 */
{
"_id" : ObjectId("3"),
"range" : {
"start" : "500",
},
"products" : [
{
"id" : "01",
"name" : "First Product",
"type" : "First Type"
},
{
"id" : "02",
"name" : "Second Product",
"type" : "Second Type"
}
]
}
第二集股票
/* 1 */
{
"_id" : ObjectId("1"),
"range" : {
"start" : "00"
},
"products" : [
{
"id" : "01",
"expired" : false,
"returned" : false
},
{
"id" : "02",
"expired" : false,
"returned" : false
}
]
}
/* 2 */
{
"_id" : ObjectId("02"),
"range" : {
"start" : "100"
},
"products" : [
{
"id" : "01",
"expired" : true,
"returned" : true
},
{
"id" : "02",
"expired" : true,
"returned" : true
}
{
"id" : "03",
"expired" : true,
"returned" : true
}
]
}
现在,我们想从上面两个集合中获得一个具有合并结果的视图
For each range document in Range collections
if Range.range.start = Stock.range.start
if Range.products.id = Stock.products.id
copy "expired" and "returned" field from Stock for that product and
add to Range.product
end if
end if
Return Range
最后的结果如下
/* 1 */
{
"_id" : ObjectId("1"),
"range" : {
"start" : "00"
},
"products" : [
{
"id" : "01",
"name" : "FirstProduct",
"type" : "First Type"
"expired" : false,
"returned" : false
},
{
"id" : "02",
"name" : "Second Product",
"type" : "Second Type"
"expired" : false,
"returned" : false
}
]
}
/* 2 */
{
"_id" : ObjectId("2"),
"range" : {
"start" : "100",
},
"products" : [
{
"id" : "01",
"name" : "First Product",
"type" : "First Type",
"expired" : true,
"returned" : true
},
{
"id" : "02",
"name" : "Second Product",
"type" : "Second Type",
"expired" : true,
"returned" : true
}
]
}
/* 3 */
{
"_id" : ObjectId("3"),
"range" : {
"start" : "500",
},
"products" : [
{
"id" : "01",
"name" : "First Product",
"type" : "First Type"
},
{
"id" : "02",
"name" : "Second Product",
"type" : "Second Type"
}
]
}
我从阶段开始,没有得到正确的查询。
如果有人能提供正确语法和正确聚合函数的帮助。
提前感谢。您需要合并两个集合中的数据,但是您必须使用才能通过product.id
匹配相应的文档。在最后一步中,您可以使用获取阵列:
db.Range.aggregate([
{
$lookup: {
from: "Stock",
localField: "range.start",
foreignField: "range.start",
as: "stock"
}
},
{
$unwind: "$stock"
},
{
$unwind: "$products"
},
{
$unwind: "$stock.products"
},
{
$match: { $expr: { $eq: [ "$products.id", "$stock.products.id" ] } }
},
{
$group: {
_id: "$_id",
"range": { $first: "$range" },
products: {
$push: {
id: "$products.id",
name: "$products.name",
type: "$products.type",
expired: "$stock.products.expired",
returned: "$stock.products.returned"
}
}
}
}
])
编辑:可选择的解决方案,它直接在阵列上使用和下面的命令进行操作。缺点是代码可读性较差,但好的方面是,当不存在匹配项时,它应该返回文档,并且使用这种方法可以获得更好的性能
db.Range.aggregate([
{
$lookup: {
from: "Stock",
localField: "range.start",
foreignField: "range.start",
as: "stock"
}
},
{
$unwind: "$stock"
},
{
$addFields: {
products: {
$map: {
input: "$products",
as: "p",
in: {
$let: {
vars: {
stockItem: {
$arrayElemAt: [
{ $filter: { input: "$stock.products", cond: { $eq: [ "$$p.id", "$$this.id" ] } } }, 0
]
}
},
in: {
$cond: [
{ $eq: [ "$$stockItem", undefined ] },
"$$p",
{
id: "$$p.id",
name: "$$p.name",
type: "$$p.type",
expired: "$$stockItem.expired",
returned: "$$stockItem.returned",
}
]
}
}
}
}
}
}
},
{
$project: {
stock: 0
}
}
])
我从来没有使用过这个功能,所以我不确定它的成本效益,但它看起来像上面这样的管道可以用来创建一个
视图
,在这个视图上可以运行find()查询@Bajal是的,这可以作为管道参数传递,谢谢回复。是否可以从输入文档中获取所有字段值,而不是像“range”那样逐个获取它:{$first:“$range”}。正如示例中所示,只有字段存在,但实际问题中有许多字段存在。所以它将包含输入文档的所有字段+推送字段。@SanjayJain您可以先将$first用于所有字段。由于它们来自同一个文档(按_id分组),它们都将具有相同的值谢谢,而且产品条目仅在$eq:[“$products.id”,“$stock.products.id”]的情况下使用,但如果不匹配,则我需要不带out expire和return元素的产品条目。