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,我正在考虑地址子文档…哈哈