node.js - Mongodb查找具有组合结果的元素数组
问题描述
这是我的两个文件
订单文件:
{
"_id":"02a33b9a-284c-4869-885e-d46981fdd679",
"context":{
"products":[
{
"id": "e68fc86a-b4ad-4588-b182-ae9ee3db25e4",
"version": "2020-03-14T13:18:41.296+00:00"
}
],
},
}
产品文件:
{
"_id":"e68fc86a-b4ad-4588-b182-ae9ee3db25e4",
"context":{
"name": "My Product",
"image": "someimage"
},
}
所以我试图在订单文档中查找产品,但结果应该包含组合字段,如下所示:
"products":[
{
"_id": "e68fc86a-b4ad-4588-b182-ae9ee3db25e4",
"version": "2020-03-14T13:18:41.296+00:00",
"name": "My Product",
"image": "someimage"
}
],
不知道该怎么做,我应该在查找之外还是在内部进行?这是我的聚合
Orders.aggregate([
{
"$lookup":{
"from":"products",
"let":{
"products":"$context.products"
},
"pipeline":[
{
"$match":{
"$expr":{
"$in":[
"$_id",
"$$products.id"
]
}
}
},
{
"$project":{
"_id":0,
"id":1,
"name":"$context.name"
}
}
],
"as":"mergedProducts"
}
},
{
"$project":{
"context":"$context",
"mergedProducts":"$mergedProducts"
}
},
]);
解决方案
您需要在外部运行该映射,方法$lookup
是运行$map和$arrayElemAt以从两个数组中获取单对,然后应用$mergeObjects以获取一个对象:
db.Order.aggregate([
{
$lookup: {
from: "products",
localField: "context.products.id",
foreignField: "_id",
as: "productDetails"
}
},
{
$addFields: {
productDetails: {
$map: {
input: "$productDetails",
in: {
_id: "$$this._id",
name: "$$this.context.name"
}
}
}
}
},
{
$project: {
_id: 1,
"context.products": {
$map: {
input: "$context.products",
as: "prod",
in: {
$mergeObjects: [
"$$prod",
{ $arrayElemAt: [ { $filter: { input: "$productDetails", cond: { $eq: [ "$$this._id", "$$prod.id" ] } } }, 0 ] }
]
}
}
}
}
}
])
最后一步的目标是获取两个数组:products
和productDetails
(的输出$lookup
)并找到它们之间的匹配项。我们知道总会有一场比赛,所以我们只能得到一件物品$arrayElemAt 0
。作为输出,$map
将有一个包含“合并”文档的数组。
推荐阅读
- mongodb - MongoDB 集合 toArray() 长度比 collection.count() 少 20
- javascript - 如何在浏览器中使用为nodejs编写的简单函数
- c# - 在应用程序运行时安装字体
- reactjs - TypeError:无法读取反应应用程序中未定义的属性“推送”
- android - 运行应用程序时出现错误“$flutterSdkpath\packages\flutter_tools\gradle\app_plugin_loader.gradle”
- javascript - 在 vuejs 中页面刷新(shift+F5)期间调用了哪个生命周期方法?
- python-3.x - 从维基百科页面抓取所有图像
- c++ - 如何使用 spdlog 打印 std::map
- scala - 在 nullSafeJoin scala spark 之后避免重复库
- java - 在 N 个线程中并行运行相同的测试 M 次