Mongodb 更改数组中属性的名称

Mongodb 更改数组中属性的名称,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,这是聚合函数,我需要获取集合中每个用户的所有产品,到目前为止我已经实现了: db.getCollection('users').aggregate([ { $lookup:{ from:"products", localField: "id", foreignField: "user_id", as: "user_products" } }, { $project:{ name:1, user_products:{NAME:1,PRICE:1}

这是聚合函数,我需要获取集合中每个用户的所有产品,到目前为止我已经实现了:

db.getCollection('users').aggregate([
{
  $lookup:{
   from:"products",
   localField: "id",
   foreignField: "user_id",
   as: "user_products"
  }
},
{
  $project:{
    name:1,
    user_products:{NAME:1,PRICE:1}
  }
}
]).pretty()

结果如下:

[
{
  name:"Felipe Blanco",
  user_products:[
    {NAME:"LAPTOP",PRICE:10},
    {NAME:"CAR",PRICE:10}
  ]

}
[
{
  name:"Felipe Blanco",
  user_products:[
    {product_name:"LAPTOP",product_price:10},
    {product_name:"CAR",product_price:10}
  ]

}
]

现在我需要更改use\u products数组中对象属性的名称,如下所示:

[
{
  name:"Felipe Blanco",
  user_products:[
    {NAME:"LAPTOP",PRICE:10},
    {NAME:"CAR",PRICE:10}
  ]

}
[
{
  name:"Felipe Blanco",
  user_products:[
    {product_name:"LAPTOP",product_price:10},
    {product_name:"CAR",product_price:10}
  ]

}
]

这是您使用的地方:

运算符迭代数组并在“表达式”中的“
”中返回结果。由于这些现在是数组中的“单个成员”,因此可以使用显式名称作为变量,并重新分配给新的键名称

例如,您不能像以下那样直接分配变量:

{ "$project": { "user_products": { "product_name": "$user_products.NAME" } }} }
因为
“$user\u products”
指的是“数组”,而MongoDB将其解释为“指定属性的数组”,这不是您想要的,也不是您使用它的原因

结果是:


花式版本 如果您不喜欢对所有键进行硬编码,并且希望对现有名称添加前缀和“小写”,那么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"
              }
            }
          }
        }
      }
    }
  }}
])

这比简单地指定每个键要冗长得多,但如果这种“前缀”是你的真实意图,它确实有它的用途。

@SamipSuwal我想是的,老实说,我甚至都没想看。可能需要注意的是,在编写答案(实际上是我的答案)时,您根本无法像
“$user\u products.NAME”
这样获取数组中的属性。我确实在这里的答案中记下了您不想这样做的原因,并添加了一些来自最新版本的好东西:)。至于复制品,我会让其他人来判断。@SamipSuwal坦白说,它是否被标记为复制品并不重要。绝大多数被标记为这样的帖子仅仅保留在网站上,只是有一个指向另一个问题的突出链接。然后两者基本上都是可搜索的,并且都会在站点的相关侧栏中显示该突出的装置。坦率地说,更多的人在查看或发布问题时应该关注这些问题。就像我说的,我可以自己标记并关闭它,但现在我将把这个决定留给其他人。