这是聚合函数,我需要获取属于集合中每个用户的所有产品,到目前为止我已经实现了:
db.getCollection('users').aggregate([
{
$lookup:{
from:"products",
localField: "id",
foreignField: "user_id",
as: "user_products"
}
},
{
$project:{
name:1,
user_products:{NAME:1,PRICE:1}
}
}
])相当();
结果是:
[
{
name:"Felipe Blanco",
user_products:[
{NAME:"LAPTOP",PRICE:10},
{NAME:"CAR",PRICE:10}
]
}
现在我需要更改 use_products数组中对象属性的名称,如下所示:
[
{
name:"Felipe Blanco",
user_products:[
{product_name:"LAPTOP",product_price:10},
{product_name:"CAR",product_price:10}
]
}
答案 0 :(得分:3)
这是您使用$map
的地方:
db.getCollection('users').aggregate([
{ "$lookup":{
"from": "products",
"localField": "id",
"foreignField": "user_id",
"as": "user_products"
}},
{ "$project": {
"name": 1,
"user_products": {
"$map": {
"input": "$user_products",
"as": "up",
"in": {
"product_name": "$$up.NAME",
"product_price": "$$up.PRICE"
}
}
}
}}
])
$map
运算符迭代数组并在"in"
表达式中返回结果。由于这些现在是"个人成员"从数组中,您可以使用显式名称作为变量并重新分配给新的键名。
你不能例如直接分配变量,如:
{ "$project": { "user_products": { "product_name": "$user_products.NAME" } }} }
因为"$user_products"
引用了"数组",并且MongoDB将其解释为"指定属性的数组" ,这不是您想要什么,以及为什么要使用$map
。
$map
的结果是:
{
"_id" : ObjectId("594876e07011be147496f076"),
"name" : "Felipe Blanco",
"user_products" : [
{
"product_name" : "LAPTOP",
"product_price" : 10
},
{
"product_name" : "CAR",
"product_price" : 10
}
]
}
如果您不想对所有密钥进行硬编码,并且您希望使用前缀和"小写"现有的名称,然后MongoDB 3.4添加了$objectToArray
和$arrayToObject
管道函数,允许您以更动态的方式执行此操作:
db.getCollection('users').aggregate([
{ "$lookup":{
"from": "products",
"localField": "id",
"foreignField": "user_id",
"as": "user_products"
}},
{ "$project": {
"name": 1,
"user_products": {
"$map": {
"input": "$user_products",
"as": "up",
"in": {
"$arrayToObject": {
"$map": {
"input": { "$objectToArray": "$$up" },
"as": "p",
"in": {
"k": { "$concat": [ "product_", { "$toLower": "$$p.k" } ] },
"v": "$$p.v"
}
}
}
}
}
}
}}
])
这比简单地指定每个密钥要长得多,但如果有这样的"前缀"它确实有它的用途。是你的实际意图。