如何使用 $set 和点表示法使用相应的旧元素更新嵌入的数组元素? [英] How to use $set and dot notation to update embedded array elements using corresponding old element?

查看:20
本文介绍了如何使用 $set 和点表示法使用相应的旧元素更新嵌入的数组元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 MongoDb 中有以下文档:

I have following documents in a MongoDb:

from pymongo import MongoClient
client = MongoClient(host='my_host', port=27017)
database = client.forecast
collection = database.regions
collection.delete_many({})
regions = [
    {
        'id': 'DE',
        'sites': [
            {
                'name': 'paper_factory',
                'energy_consumption': 1000
            },
            {
                'name': 'chair_factory',
                'energy_consumption': 2000
            },
        ]
    },
    {
        'id': 'FR',
        'sites': [
            {
                'name': 'pizza_factory',
                'energy_consumption': 3000
            },
            {
                'name': 'foo_factory',
                'energy_consumption': 4000
            },
        ]
    }
]
collection.insert_many(regions)

现在我想将属性 sites.energy_consumption 复制到每个站点的新字段 sites.new_field:

Now I would like to copy the property sites.energy_consumption to a new field sites.new_field for each site:

set_stage = {
    "$set": {
        "sites.new_field": "$sites.energy_consumption"
    }
}

pipeline = [set_stage]
collection.aggregate(pipeline)

但是,不是复制每个站点的单个值,而是收集所有站点值并添加为一个数组.代替 'new_field': [1000, 2000] 我想为第一个站点获得 'new_field': 1000:

However, instead of copying the individual value per site, all site values are collected and added as an array. Intead of 'new_field': [1000, 2000] I would like to get 'new_field': 1000 for the first site:

{
    "_id": ObjectId("61600c11732a5d6b103ba6be"),
    "id": "DE",
    "sites": [
      {
        "name": "paper_factory",
        "energy_consumption": 1000,
        "new_field": [
          1000,
          2000
        ]
      },
      {
        "name": "chair_factory",
        "energy_consumption": 2000,
        "new_field": [
          1000,
          2000
        ]
      }
    ]
  },
  {
    "_id": ObjectId("61600c11732a5d6b103ba6bf"),
    "id": "FR",
    "sites": [
      {
        "name": "pizza_factory",
        "energy_consumption": 3000,
        "new_field": [
          3000,
          4000
        ]
      },
      {
        "name": "foo_factory",
        "energy_consumption": 4000,
        "new_field": [
          3000,
          4000
        ]
      }
    ]
  }

=>什么表达式可以只使用数组的对应项?

是否有某种当前索引运算符:

$sites[<current_index>].energy_consumption

替代点运算符(会提醒我 * 乘法和 .* 元素矩阵乘法之间的区别)?

or an alternative dot operator (would remind me on difference between * multiplication and .* element wise matrix multiplication)?

$sites:energy_consumption

或者这是一个错误?

编辑

我也尝试使用$"位置运算符,例如与

I also tried to use the "$" positional operator, e.g. with

sites.$.new_field

$sites.$.energy_consumption

但后来我得到了错误

FieldPath field names may not start with '$'

相关:

https://docs.mongodb.com/manual/reference/operator/aggregation/set/#std-label-set-add-field-to-embedded

在MongoDB 如何使用 $set 更新嵌套值/嵌入文档?

推荐答案

如果通过选择该字段是数组的成员,则您将选择所有这些字段.

If the field is member of an array by selecting it you are selecting all of them.

{ar :[{"a" : 1}, {"a" : 2}]}

"$ar.a" = [1 ,2]

此外,您不能将更新运算符与聚合混合使用,也不能使用诸如$sites.$.energy_consumption,如果您要进行聚合,则必须使用聚合运算符,只有在 $match 阶段可以使用查询运算符.

Also you cant mix update operators with aggregation, you cant use things like $sites.$.energy_consumption, if you are doing aggregation you have to use aggregate operators, with only exception the $match stage where you can use query operators.

查询

  • 使用 $setField
  • 的替代解决方案与您的略有不同
  • 我想它会更快,但可能差别不大
  • 不需要使用 javascript,它会变慢
  • 这是 >= MongoDB 5 解决方案,$setField 是新的运算符
  • alternative slightly different solution from yours using $setField
  • i guess it will be faster, but probably little difference
  • no need to use javascript it will be slower
  • this is >= MongoDB 5 solution, $setField is new operator

此处测试代码

aggregate(
[{"$set":
  {"sites":
   {"$map":
    {"input":"$sites",
     "in":
     {"$setField":
      {"field":"new_field",
       "input":"$$this",
       "value":"$$this.energy_consumption"}}}}}}]
)

这篇关于如何使用 $set 和点表示法使用相应的旧元素更新嵌入的数组元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆