Reputation: 960
I have this collection. I am trying to add object(item = {label: "Chrome", value: "chrome"}) to the array only if the value
is unique, i.e. insert the whole object, item
in the array foo
only if array foo
doesn't have any other object with the same value as item
, using one MongoDB operation
foo=[{label:"IE",value:"ie"},{label:"Firefox",value:"firefox"}]
Upvotes: 1
Views: 475
Reputation: 5669
i don't think $addToSet supports duplicate detection of object fields like you want. however you could do it like this:
db.bars.update(
{
"_id": ObjectId("5d3421a6a0100c1e083356e1"),
"foo": {
"$not": {
"$elemMatch": {
"value": "firefox"
}
}
}
},
{
"$push": {
"foo": {
"label": "Fake Fox",
"value": "firefox"
}
}
}
)
first you match the parent object by id + that it doesn't contain "firefox" as the value in the foo object array. then you specify a $push
to add your new object to the foo array. that way, no duplicates will be created in the foo array.
not sure what your coding language is but here's the c# code that generated the above mongo query in case anybody's interested:
using MongoDB.Entities;
using System.Linq;
namespace StackOverflow
{
public class Program
{
public class bar : Entity
{
public item[] foo { get; set; }
}
public class item
{
public string label { get; set; }
public string value { get; set; }
}
private static void Main(string[] args)
{
new DB("test");
var bar = new bar
{
foo = new[]
{
new item { label = "IE", value = "ie"},
new item { label = "FireFox", value = "firefox" }
}
};
bar.Save();
var chrome = new item { label = "Chrome", value = "chrome" };
var firefox = new item { label = "Fake Fox", value = "firefox" };
DB.Update<bar>()
.Match(b =>
b.ID == bar.ID && !b.foo.Any(i => i.value == chrome.value))
.Modify(x => x.Push(b => b.foo, chrome))
.Execute();
DB.Update<bar>()
.Match(b => b.ID == bar.ID && !b.foo.Any(i => i.value == firefox.value))
.Modify(x => x.Push(b => b.foo, firefox))
.Execute();
}
}
}
Upvotes: 2