Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 更新MongoDb子文档数组中的特定文档_Node.js_Mongodb - Fatal编程技术网

Node.js 更新MongoDb子文档数组中的特定文档

Node.js 更新MongoDb子文档数组中的特定文档,node.js,mongodb,Node.js,Mongodb,我有一个文档用户,其架构为: { "_id" : ObjectId("57b2d706f61d04e8d99dd983"), "addressesAsVendor" : [ { "_id" : "V1", "addressLine1" : "al1", "addressLine2" : "al2", "street" : "street", "

我有一个文档用户,其架构为:

{
    "_id" : ObjectId("57b2d706f61d04e8d99dd983"),
    "addressesAsVendor" : [ 
        {
            "_id" : "V1",
            "addressLine1" : "al1",
            "addressLine2" : "al2",
            "street" : "street",
            "city" : "city",
            "country" : "IN",
            "pincode" : "490020",
            "location" : {
                "latitutde" : "lat1",
                "longitude" : "lon1"
            }
        }, 
        {
            "_id" : "V2",
            "addressLine1" : "al1",
            "addressLine2" : "al2",
            "street" : "street",
            "city" : "city",
            "country" : "IN",
            "pincode" : "490020",
            "location" : {
                "latitutde" : "lat2",
                "longitude" : "lon2"
            }
        }
    ]
}
现在,假设我想用以下数据更新用户id57b2d706f61d04e8d99dd983中的AddresseSavendor数组的V1id:

{
    "addressLine1" : "al1 new",
    "addressLine2" : "al2 new",
    "street" : "street new",
    "city" : "city new",
    "country" : "IN new",
    "pincode" : "490020 new",
    "location" : {
       "latitutde" : "lat1 new",
       "longitude" : "lon1 new"
    }
}
因此,新用户文档将如下所示:

{
    "_id" : ObjectId("57b2d706f61d04e8d99dd983"),
    "addressesAsVendor" : [ 
        {
            "_id" : "V1",
            "addressLine1" : "al1 new",
            "addressLine2" : "al2 new",
            "street" : "street new",
            "city" : "city new",
            "country" : "IN new",
            "pincode" : "490020 new",
            "location" : {
              "latitutde" : "lat1 new",
              "longitude" : "lon1 new"
            }
        }, 
        {
            "_id" : "V2",
            "addressLine1" : "al1",
            "addressLine2" : "al2",
            "street" : "street",
            "city" : "city",
            "country" : "IN",
            "pincode" : "490020",
            "location" : {
                "latitutde" : "lat2",
                "longitude" : "lon2"
            }
        }
    ]
}
如何在MongoDb中实现这一点,以及保持多个地址的最佳方式是什么,这些地址可以很容易地显示在用户的地址页面中,并且负载最小,我的意思是在需要时可以很容易地访问

请发表意见。
:)

您可以使用位置操作符执行更新:

var data = {
    "addressLine1" : "al1 new",
    "addressLine2" : "al2 new",
    "street" : "street new",
    "city" : "city new",
    "country" : "IN new",
    "pincode" : "490020 new",
    "location" : {
       "latitutde" : "lat1 new",
       "longitude" : "lon1 new"
    }
};

collection.update(
    { "addressesAsVendor._id" : "V1" },
    { "$set": { "addressesAsVendor.$": data  } }, 
    function(err, result) {
         if (err) return handleError(err);
         console.log(result);
    }
)
上面的位置运算符保存与查询匹配的数组中元素的索引(在上面的情况下为0)。这意味着,如果您事先知道元素的位置(这在现实生活中几乎是不可能的),您可以将update语句更改为:
{“$set”:{“addressesAsVendor.0”:data}

由于位置运算符充当与查询文档匹配的第一个元素的占位符,并且数组字段必须作为查询文档的一部分出现,因此查询
{“addressesAsVendor.\u id:“V1”}
对于使
$
运算符正常工作至关重要

请注意,位置操作员(目前)仅更新第一个相关文档,对此有一个记录单


对于您的后续问题,该问题旨在找到保存多个地址的最佳方式,这些地址可以轻松显示在用户的地址页面中,并且负载最小:

与创建单独的地址集合相比,您当前的模式是一种更好的方法,因为单独的集合需要更多的工作,即查找用户及其地址需要两次查询,并且需要额外的工作,而上述模式嵌入的文档很容易且快速(单次搜索)。插入和更新没有太大区别。因此,如果您需要选择单个文档、需要对查询进行更多控制或拥有大量文档,则单独的集合是很好的。当您需要整个文档时,嵌入文档是好的,该文档包含嵌入的
地址savander
$slice
,或者根本没有地址

一般来说,如果你有很多“地址”,或者地址很大,最好是单独收集


较小和/或更少的文档通常适合嵌入。

您可以使用updateOne(MongoDB查询)来更新文档

NodeJS等效值为:-

collection.update(criteria, update[[, options], callback]);
请相应地更改对象id

db.address.updateOne({ "_id" : ObjectId("57c04425c400a6b59c9bc1ee"), "addressesAsVendor._id" : "V1" }, { $set: { "addressesAsVendor.$.addressLine1" : "al1 new", 
   "addressesAsVendor.$.addressLine2" : "al2 new",
            "addressesAsVendor.$.street" : "street new",
            "addressesAsVendor.$.city" : "city new",
            "addressesAsVendor.$.country" : "IN new",
            "addressesAsVendor.$.pincode" : "490020 new",
            "addressesAsVendor.$.location" : {
              "latitutde" : "lat1 new",
              "longitude" : "lon1 new"
            }
    } });

很好的解释,谢谢@chridam,这也是正确的方法还是我应该一起使用不同的地址集合?我已经用后续的问题回答更新了我的答案。考虑到电子商务网站的正常情况,用户的地址最多为10、15、20(除此之外,可能我错了,如果我错了,请纠正我),无论如何,它不是地址簿,所以对于这20个文档,我认为使用这种方法更好,对吗?你是对的,如果一个文档最多有20个用于地址的嵌入文档,那么只要该文档(包括其所有嵌入的文档和数组)不能超过16MB,就可以了。但是,不要担心我会有一点担心nt,威廉·莎士比亚的全集大约有5.5MB:)这意味着在这个文档中可以保存几乎3部莎士比亚的作品:D,我正在考虑地址子文档…哈哈