在 MongoDB 文档中更新插入匹配条件的数组元素?
我想更新插入数组元素,因此如果不匹配则插入它,否则更新它。
我尝试了这个问题的答案,如果数组元素已经存在,它就可以正常工作。如果该元素不存在,则会在数组字段下创建“$”的子元素。
我的 Mongo 结构如下:
Widget (collection)
--Name
--Properties (array)
--Name
--Value
我的应用程序从 WebService 调用获取小部件名称和属性列表。我希望迭代提供的属性并更新 MongoDB 中的值(如果名称已存在),或者将新属性插入到属性数组(如果不存在)。
As per How do I update Array Elements matching criteria in a MongoDB document?
I want to upsert the array elements, so if one doesnt match then insert it, otherwise update it.
I tried the answer on that question, and it works fine IF the array element already exists. If the element doesnt exist then it creates a child of "$" under the array field.
My Mongo structure is as follows:
Widget (collection)
--Name
--Properties (array)
--Name
--Value
My application gets a Widget Name and a list of Properties from a WebService call. I wish to iterate the provided Properties and update the value in the MongoDB if the Name already exists, OR insert a new Property to the Properties array if it doesnt.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果没有一些应用程序端逻辑,使用单个更新是不可能实现您所需要的。请注意,upsert 作为一项功能与此特定问题无关,除非您希望在不存在具有所提供名称的 Widget 文档的情况下自动创建新的 Widget 文档。
您遇到的问题是,没有任何功能允许您根据数组元素的存在进行两次不同的更新。您仅有的两个选择是:
What you require is not possible using a single update without some app-side logic. Note that upsert as a feature is not relevant for this specific problem unless you want to automatically create new Widget documents if none exist with the provided name.
The problem you're running into is that there is no functionality that allows you to do two different updates depending on the existence of an array element. Your only two options are :
您无法自动更新插入数组元素。但是,如果您可以重组文档以使用对象而不是数组,那么这在原子上是可能的。使用您的符号,结构将是
示例文档将是
要更新插入名为“property-3”且值为 300 的项目,您需要做
一个缺点是查询字段名称(使用
$exists
查询运算符)需要扫描。您可以通过添加一个存储属性名称的额外数组字段来解决此问题。该字段可以正常索引和查询。更新插入变成(请记住
$addToSet
的时间复杂度为 O(n)。)删除属性时,您还必须将其从数组中拉出。You cannot atomically upsert array elements. But if you can restructure your document to use an object instead of an array, then this is atomically possible. Using your notation, the structure would be
An example document would be
To upsert an item named 'property-3' with value 300, you'd do
One drawback is that querying for field names (using the
$exists
query operator) requires scanning. You can get around this by adding an extra array field that stores the property names. This field can be indexed and queried normally. Upserts become(Keep in mind
$addToSet
is O(n).) When removing a property, you have to pull it from the array as well.至少在 php 中它对我有用,尝试采用你的语言。
您需要您的集合看起来像:
它插入新名称(如果不存在)并更新那些已经存在的名称
At least in php it works for me, try to adopt to your language.
You need your collection look like:
It inserts new names if not exist and updates those which already there