I’am currently playing around with MongoDB using its C# driver, trying each method in the API (which would be leagues better if they provided some examples) one by one.
And currently I’m on the Update.PullAll() method.
I’m using this POCO object for my tests:
public class Person
{
public ObjectId Id { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
public List<Skill> Skills { get; set; }
}
public class Skill
{
public Object Id { get; set; }
public string Name { get; set; }
}
If populated, translates into this json object:
{
"_id": ObjectId("4f979621682dbc1a8cefecb3"),
"Firstname" : "John",
"Lastname" : "Doe",
"Skills" : [
{
"_id" : ObjectId("4f979621682dbc1a8cefecaf"),
"Name" : "C#.NET"
},
{
"_id" : ObjectId("4f979621682dbc1a8cefecb0"),
"Name" : "ASP.NET"
},
{
"_id" : ObjectId("4f979621682dbc1a8cefecb1"),
"Name" : "SQL Server"
}
]
}
Now, I’m trying to remove the elements from the skills collection.
Here is my code:
var server = MongoServer.Create("mongodb://localhost/?safe=true");
var db = server.GetDatabase("test");
var collection = db.GetCollection<Person>("person");
// Retrieve the data above from mongoDB
var _person = collection.AsQueryable()
.Select(p => p).Single();
// Query to reference "John Doe"
var query = Query.EQ("_id",new ObjectId(_person.Id.ToString()));
// Collection of "John Doe's" skill ids
var objIds = _person.Skills
.Select(p => new ObjectId(p.Id.ToString()));
// Parse the skill ids to a BsonArray
var bsonArray = BsonArray.Create(objIds);
var update = Update.PullAll("Skills" , bsonArray);
// Call the Update command
collection.Update( query, update );
Which, does nothing; it leaves my json object intact.
Can anyone help me point out where did I go wrong in my code?
Any suggestion is much appreciated, thanks.
For
$pullAllto work, you have to match the whole object exactly, and cannot use just one field (even if it is called _id).So you’d have to include the name as well in the update command (and the fields need to be in the same order, too).
The command you really want to use is
$pull, which does what you need here, i.e. matching filtering criteria:Even though it is called “pull without all”, it does pull all matched elements, not just one. The “all” just means that you have one filter (whereas pullAll has multiple elements to match).