Here is an example document from my collection:
Books
[
id: 1,
links:
[
{text: "ABC", "url": "www.abc.com"},
{text: "XYZ", "url": "www.xyz.com"}
]
]
I want to replace the links array in one update operation. Here is an example of how the above document should be modified:
Books
[
id: 1,
links:
[
{text: "XYZ", "url": "www.xyz.com"},
{text: "efg", "url": "www.efg.com"}, <== NEW COPY OF THE ARRAY
{text: "ijk", "url": "www.ijk.com"}
]
]
As you can see, the links array has been replaced (old data removed, and new data added).
I am having very hard time with the Update.Set()
because it says it MyLinks<>
cannot be mapped to a BsonValue
I've tried many different ways of achieving this, and all of them fail, including .PushAllWrapped<WebLinkRoot>("links", myDoc.WebLinks)
.
Everything I've tried results in the new values being appended to the array, rather than the array being replaced.
As it seems MongoDB doesn't provide a simple method to replace an array of subdocument OR a method like .ClearArray()
, what is the best way for me to ensure the array is cleared before adding new elements in a single query?
I think you have to do something like this:
var newArray = new BSONArray {
new BSONDocument { { "text", "XYZ" }, { "url", "www.xyz.com" } },
new BSONDocument { { "text", "efg" }, { "url", "www.efg.com" } },
new BSONDocument { { "text", "ijk" }, { "url", "www.ijk.com" } }
};
var update = Update.Set( "links", newArray );
collection.Update( query, update );
Or whatever method you can to cast as a valid BSONValue.
So equivalent to shell:
{ "links" : [ { "text" : "abc" } ] }
> db.collection.update(
{},
{ $set:
{ links: [
{ text: "xyz", url: "something" },
{ text: "zzz", url: "else" }
]}
})
>db.collection.find({},{ _id: 0, links:1 }).pretty()
{ "links" : [
{
"text" : "xyz",
"url" : "something"
},
{
"text" : "zzz",
"url" : "else"
}
]
}
So that works.
You clearly need something else other than embedded code. But hopefully that puts you on the right track.