根据mongodb中另一个数组字段的值将数组字段添加到集合中

时间:2015-02-22 08:08:15

标签: mongodb mongodb-query aggregation-framework

我有一个具有以下结构的集合,如一个文档所示

{
_id : 1,
array1 : [{fld1 : 'doc1e1fld1', fld2: 'doc1e1fld2'},{fld1:'doc1e2fld1',fld2: 'doc1e2fld2'}]
}

我想在集合中的所有元素中添加另一个字段,并设置值,使得上面修改过的doc看起来像:

{
    _id : 1,
    array1 : [{fld1 : 'doc1e1fld1', fld2: 'doc1e1fld2'},{fld1:'doc1e2fld1',fld2: 'doc1e2fld2'}],
    array2 : ['doc1e1fld1','doc1e2fld1']
    }

基本上将新数组元素添加到集合中的所有文档,并将其内容设置为数组,该数组是文档array1中所有元素的fld1值。

我看了一下Update MongoDB field using value of another field,但我不明白我怎么能提取某些元素。

1 个答案:

答案 0 :(得分:2)

所以你应该从你引用的问题中意识到,在更新另一个字段时,你实际上不能引用文档中的另一个值而实际上没有查找文档并循环结果以生成更新。

所以最重要的是你要真正在代码中执行此操作,读取每个文档并提取新值以构成新数组。通过在更新中使用$set$push运算符,可以使用$each或更安全地创建新阵列。

理想情况下,您也可以使用Bulk Operations API获得最佳的更新形式。

最后,您还可以将一些数组构造工作负载委派给aggregation framework,而不是在客户端代码中处理所有这些工作负载,但仍需要对结果执行更新:

var bulk = db.collection.initializeOrderedBulkOp();
var count = 0;

var cursor = db.collection.aggregate([
    { "$project": {
        "array2": {
            "$map": {
                "input": "array1",
                "as": "el",
                "in": "$$el.fld1"
            }
        }
    }}
]);

cursor.forEach(function(doc) {
    bulk.find({ "_id": doc._id }).updateOne({ 
        "$push": { "array2": { "$each": doc.array2 } }
    });
    count++;

    // send and drain once every 1000 documents
    if ( count % 1000 == 0 ) {
        bulk.execute();
        bulk = db.collection.initializeOrderedBulkOp();
    }
});

// If the counter is uneven then send
if ( count % 1000 != 0 )
    bulk.execute();

就是这样。您可以将聚合框架与$map运算符一起使用,以便从数组中提取所需的元素,或者您可以使用类似的方法在代码中执行此操作,并考虑到您并未真正“聚合”任何内容。这里的主要情况是,您将需要在代码中循环结果,无论您使用何种语言。

当然,如果您只是创建一个带有更改结果的“新”集合,那么聚合的$out管道阶段可能很适合您:

db.collection.aggregate([
    { "$project": {
        "array1": 1,
        "array2": {
            "$map": {
                "input": "array1",
                "as": "el",
                "in": "$$el.fld1"
            }
        }
    }},
    { "$out": "newcollection" }
]);

简而言之,你想要一些或所有这些技巧,以获得你正在寻找的改变的收集结果。所以要么直接使用它,要么实现其中的一部分。

相关问题