问题
We've been struggling for hours on a query that seems easy to us and that we made through Robo 3T... The issue is now to convert it into C# and we just can't find the way and we don't even understand why it doesn't work.
We have the following query:
db.getCollection('UserCollection').update({"User.Contacts._id": ObjectId("xxx")},
{
$pull: {
"User.Contacts": {
"_id": {$in:[ObjectId("xxx")]}
}
}
})
Now that our query works, we try to translate it in c# and we reached that point so far and we don't really know where the issue can come from..
public Task PullSocialInfoAsync(ObjectId contactId)
{
var fieldName = nameof(UserContainer.User) + "." + nameof(UserContainer.User.Contacts) + "._id";
var filter = NewFilterBuilder().Eq(fieldName, contactId);
var update = new BsonDocument("$pull", new BsonDocument(nameof(UserContainer.User) + "." + nameof(UserContainer.User.Contacts), new BsonDocument("_id", new BsonDocument("$in", new BsonArray() { contactId }))));
return GetCurrentCollection().FindOneAndUpdateAsync(filter, update);
}
Here you see FindOneAndUpdateAsync
, but we tried we UpdateAsync
as well, also we change multiple time the initialisation of our BsonArray with no success, even if the query as string match what we have on Robo 3T
Based on the above C# query, we have that output:
{{ "$pull" : { "User.Contacts" : { "_id" : { "$in" : [ObjectId("xxx")] } } } }}
. The most interesting part is that if I copy paste.. well it works
Any ideas?
Thanks !
回答1:
if i understood your requirement correctly, a pullFilter
is what you need.
var filter = Builders<UserCollection>.Filter.Where(u => u.User.Contacts.Any(c => c._Id == contactID));
var update = Builders<UserCollection>.Update.PullFilter(u => u.User.Contacts, c => c._Id == contactID);
collection.UpdateOne(filter, update);
here's the full program for testing if anybody's interested.
using MongoDB.Entities; // PM> Install-Package MongoDB.Entities
using MongoDB.Bson;
using System.Linq;
namespace StackOverflow
{
public class Program
{
public class UserCollection : Entity
{
public User User { get; set; }
}
public class User
{
public Contact[] Contacts { get; set; }
}
public class Contact
{
public ObjectId _Id { get; set; }
}
private static void Main(string[] args)
{
new DB("test");
var contactID = ObjectId.GenerateNewId();
(new UserCollection
{
User = new User
{
Contacts = new[]
{
new Contact { _Id = ObjectId.GenerateNewId()},
new Contact { _Id = contactID}
}
}
}).Save();
DB.Update<UserCollection>()
.Match(u => u.User.Contacts.Any(c => c._Id == contactID))
.Modify(b => b.PullFilter(u => u.User.Contacts, c => c._Id == contactID))
.Execute();
}
}
}
来源:https://stackoverflow.com/questions/57293593/c-sharp-mongodb-pull-an-item-from-a-nested-documents-array-based-on-an-id