我有一个文档用户,其架构为:
{
"_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"
}
}
]
}
现在让我们假设我要更新用户ID 57b2d706f61d04e8d99dd983 内的 addressesAsVendor 数组的 V1 ID数据:
{
"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 中实现这一目标,以及保留多个地址的最佳方式,可以在用户的“地址”页面中轻松显示,且负载最小,意思是在需要时很容易访问。
请发表您的意见。 :)
答案 0 :(得分:2)
您可以使用位置$
运算符进行更新:
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)。这意味着如果您事先知道元素的位置(在现实生活中几乎不可能),您只需将更新语句更改为:{ "$set": { "addressesAsVendor.0": data } }
。
由于位置$
运算符充当与查询文档匹配的第一个元素的占位符,并且数组字段必须作为查询文档的一部分出现,因此查询{ "addressesAsVendor._id" : "V1" }
对于获取是必不可少的 $
运算符可以正常运行。
请注意,位置$
运营商(目前)仅更新第一个相关文档,此处有 JIRA 票证。
对于您的后续问题,该问题旨在找到保留多个地址的最佳方式,这些问题可以在用户的“地址”页面中轻松显示,并且负载最小:
您当前的架构比创建单独的地址集更好,因为单独的集合需要更多的工作,即查找用户及其地址是两个查询并需要额外的工作,而上述架构嵌入式文档简单快速(单一搜索)。插入和更新没有太大区别。因此,如果您需要选择单个文档,需要对查询进行更多控制或拥有大量文档,则单独的集合是很好的。如果您需要整个文档,包含嵌入式$slice
的{{1}}或完全没有地址的文档,嵌入式文档就会很好。
作为一般规则,如果您有很多“地址”或者它们很大,那么单独的集合可能是最好的。
较小和/或较少的文档往往非常适合嵌入。
答案 1 :(得分:1)
您可以使用 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"
}
} });