栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

更新数组mongodb中的嵌套数组

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

更新数组mongodb中的嵌套数组

MongoDB 3.6及更高版本

MongoDB3.6及更高版本提供了一项新功能,该功能允许您使用位置过滤的

$[<identifier>]
语法来更新嵌套数组,以匹配特定元素并
arrayFilters
在update语句中应用不同的条件:

const { oid, pid } = req.params;const { name, oName, description, type } = req.body;collection.update(    {        "_id": 1,        "operations": { "$elemMatch": {     oid, "parameters.pid": pid }        }    },    { "$set": {         "operations.$[outer].parameters.$[inner].name": name,        "operations.$[outer].parameters.$[inner].description": description,        "operations.$[outer].parameters.$[inner].oName": oName,        "operations.$[outer].parameters.$[inner].type": type     } },    { "arrayFilters": [        { "outer.oid": oid },        { "inner.pid": pid }    ] }, (err, result) => {    if (err) {        console.log('Error updating service: ' + err);        res.send({'error':'An error has occurred'});    } else {        // console.log('' + result + ' document(s) updated');        res.send(result);    }});

对于MongoDB 3.4及更早版本:

正如@wdberkeley在他的评论中提到的:

MongoDB不支持匹配多个级别的数组。考虑更改文档模型,以便每个文档都代表一个操作,并具有操作文档中重复的一组操作所共有的信息。

我同意上述观点,并建议重新设计架构,因为MongoDB引擎不支持多个位置运算符

但是,如果您知道具有要预先更新的参数对象的操作数组的索引,则更新查询将为:

db.collection.update(    {        "_id" : "04",         "operations.parameters.pid": "011"    },     {        "$set": {  "operations.0.parameters.$.name": "foo", "operations.0.parameters.$.description": "bar",  "operations.0.parameters.$.type": "foo"         }    })

编辑:

如果您想

$set
即时创建条件,即可以帮助您获取对象索引然后进行相应修改的条件,请考虑使用
MapReduce

当前,使用聚合框架似乎不可能做到这一点。与之相关的一个未解决的未解决
JIRA问题 。但是,可以使用
MapReduce
解决。MapReduce的基本思想是它使用Javascript作为查询语言,但是它比聚合框架要慢得多,因此不应用于实时数据分析。

在您的MapReduce操作中,您需要定义几个步骤,即映射步骤(将操作映射到集合中的每个文档中,并且该操作不能执行任何操作或使用键和投影值发出某些对象)和减少步骤(它接受发射值列表并将其简化为单个元素)。

对于映射步骤,理想情况下,您希望获取集合中的每个文档,每个

operations
数组字段的索引以及包含这些
$set
键的另一个键。

您的reduce步骤将是一个简单地定义为的函数(不执行任何操作)

var reduce = function() {};

然后,MapReduce操作的最后一步将创建一个单独的集合操作,其中包含发出的操作数组对象以及带有

$set
条件的字段。在原始集合上运行MapReduce操作时,可以定期更新此集合。总而言之,此MapReduce方法如下所示:

var map = function(){    for(var i = 0; i < this.operations.length; i++){        emit(  {     "_id": this._id,      "index": i  },  {     "index": i,      "operations": this.operations[i],      "update": {         "name": "operations." + i.toString() + ".parameters.$.name",         "description": "operations." + i.toString() + ".parameters.$.description",         "type": "operations." + i.toString() + ".parameters.$.type"     }          }        );    }};var reduce = function(){};db.collection.mapReduce(    map,    reduce,    {        "out": { "replace": "operations"        }    });

operations
从MapReduce操作查询输出集合通常会给您结果:

db.operations.findOne()

输出

{    "_id" : {        "_id" : "03",        "index" : 0    },    "value" : {        "index" : 0,        "operations" : { "_id" : "96", "oName" : "test op 52222222222", "sid" : "04", "name" : "test op 52222222222", "oid" : "99", "description" : "testing", "returntype" : "test", "parameters" : [      {         "oName" : "Param1",         "name" : "foo",         "pid" : "011",         "type" : "foo",         "description" : "bar",         "value" : ""     },      {         "oName" : "Param2",         "name" : "Param2",         "pid" : "012",         "type" : "58222",         "description" : "testing",         "value" : ""     } ]        },        "update" : { "name" : "operations.0.parameters.$.name", "description" : "operations.0.parameters.$.description", "type" : "operations.0.parameters.$.type"        }    }}

然后,您可以使用

db.operations.find()
方法中的游标进行迭代,并相应地更新您的集合:

var oid = req.params.operations;var pid = req.params.parameters;var cur = db.operations.find({"_id._id": oid, "value.operations.parameters.pid": pid });// Iterate through results and update using the update query object set dynamically by using the array-index syntax.while (cur.hasNext()) {    var doc = cur.next();    var update = { "$set": {} };    // set the update query object    update["$set"][doc.value.update.name] = req.body.name;    update["$set"][doc.value.update.description] = req.body.description;    update["$set"][doc.value.update.type] = req.body.type;    db.collection.update(        { "_id" : oid,  "operations.parameters.pid": pid        },         update     );};


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/367575.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号