C# MongoDB - Pull an item from a nested document's array based on an ID

最后都变了- 提交于 2019-12-11 07:45:55

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!