获取与mongoDB

时间:2016-05-14 04:55:56

标签: node.js mongodb nosql

有没有简单的方法来获取数组元素的位置。位置在同一文档中定义为不同的字段。

示例文档:

{
    _id:"123",
    "elementPosition": 3,
    "users": [
              {
                "username": "abcd"
              },
              {
                "username": "qweqw"
              },
              {
                "username": "fdsfsd"
              },
              {
                "username": "dsfvd"
              }
    ]

}

此外,如果有一些简单的方法,那么也希望以有效的方式进行以下操作:

  1. 更新文档,其中users.elementPosition.username =" abcd"并更新" users.elementPosition.username" =" wxyz"
  2. 来自同一文档的

    *** elementPosition。

    我尝试过很多方法。其中一个是get get elementPosition,然后使用该elementPosition检查文档是否匹配。但这很脏又很冗长。

    尝试在单个查询"user."+elementPosition+".username"中使用elementPosition作为变量但不起作用。

    还尝试了不同的聚合查询方式,但没有得到好的结果。 将$elementPosition投射到下一阶段并使用它来检索特定的位置文档,但没有得到我想要的。

2 个答案:

答案 0 :(得分:1)

使用$arrayElemAt Operator

    db.collection.aggregate(
    {$match : {_id: "123"} },
    {$project : {username: {$arrayElemAt: [ "$users.username", "$elementPosition" ]}}})

答案 1 :(得分:1)

使用 bulkWrite()来解决您希望使用同一文档中定义的位置更新username = "abcd""wxyz"的文档的后续问题有效执行更新的方法。以下显示如何使用MongoDB 3.2或更高版本:

var bulkUpdateOperations = [],
    counter = 0,
    setObj = {};

db.collection.find({ 
    "users.username": "abcd",
    "elementPosition": { "$exists": true }
}).forEach(function(doc) {  
    setObj["users."+ doc.elementPosition +".username"] = "wxyz";
    bulkUpdateOperations.push({
        "updateOne": {
            "filter": { "_id": doc._id },
            "update": { "$set": setObj }
        }
    });

    if (counter % 1000 == 0) {
        db.collection.bulkWrite(bulkUpdateOperations);
        bulkUpdateOperations = [];
    }
})

if (counter % 1000 != 0) { db.collection.bulkWrite(bulkUpdateOperations); }

如果使用较早版本的MongoDB,即v2.6或3.0,请使用这些版本支持的 Bulk Operations API

var bulk = [],
    counter = 0,
    setObj = {};

db.collection.find({ 
    "users.username": "abcd",
    "elementPosition": { "$exists": true }
}).forEach(function(doc) {  
    setObj["users."+ doc.elementPosition +".username"] = "wxyz";
    bulk.find({ "_id": doc._id }).updateOne({ "$set": setObj });

    if (counter % 1000 == 0) {
        bulk.execute();
        bulk = db.collection.initializeUnorderedBulkOp();
    }
});

if (counter % 1000 != 0) { bulk.execute(); };