在MongoDb的子文档中更新数组中的特定文档
我有一个文档用户有一个模式为:
{ "_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中如何实现这一点,保持多个地址的最佳方式是什么,这可以很容易地显示在用户的地址页面,也是最小的负载,我的意思是在需要的时候很容易访问。
请摆脱你的意见。 🙂
您可以使用位置$
操作符来执行更新:
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._id" : "V1" }
对于获取$
运营商正常工作。
请注意位置$
运算符(现在)只更新第一个相关文件,这是一个JIRA票据。
对于你的后续问题,寻求保持多个地址的最佳方式,这可以很容易地显示在用户的地址页面,也是最小的负载:
你现在的模式比创build一个单独的地址集合更好,因为单独的集合需要更多的工作,即查找用户+地址是两个查询,并且需要额外的工作,而上面的模式embedded式文档是简单和快速的(单一查找)。 插入和更新没有太大的区别。 因此,如果您需要select单个文档,需要对查询进行更多的控制,或者拥有大量的文档,则单独的集合是很好的。 当你想要整个文档时,embedded式文档是很好的,文档中embedded的addressesAsVendor
$slice
的$slice
,或者根本没有地址。
一般来说,如果你有很多“地址”,或者如果他们很大,一个单独的集合可能是最好的。
较小和/或较less的文档往往是自然适合embedded的。
您可以使用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" } } });