如何使用 $set 和点表示法使用相应的旧元素更新嵌入的数组元素? [英] How to use $set and dot notation to update embedded array elements using corresponding old element?
问题描述
我在 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 '$'
相关:
在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屋!