Драйвер MongoDB C # для удаления многих не работает с фильтром

#c# #mongodb #mongodb-.net-driver #asp.net-core-2.1

#c# #mongodb #mongodb-.net-driver #asp.net-core-2.1

Вопрос:

Я пытался удалить дублирующие записи с помощью драйвера MongoDB C #. Приведенный ниже скрипт не выдает ошибку и не удаляет какую-либо запись. Есть какие-нибудь советы?

 [BsonIgnoreExtraElements]
public class ApiUsers
{
    [BsonId]
    [BsonRepresentation(BsonType.String)]
    public ObjectId Id { get; set; }
    
    public string UserEMail { get; set; }
}

var users = _mongoDbContext.ApiUsers.Find(f => f.UserEMail == email).ToList();
var oneUser = users[0];

var idsToDelete = users.Where(x => !x.Id.Equals(oneUser.Id)).Select(x => x.Id);
if (idsToDelete.Any())
{   //Delete Dublicates
    
    var idsToDeleteFilter = Builders<ApiUsers>.Filter.In(t => t.Id, idsToDelete);
    var result = _mongoDbContext.ApiUsers.DeleteMany(idsToDeleteFilter);
} 
  

Я попробовал также метод DeleteOne, как показано ниже, но он тоже не сработал,

 foreach (var idToDelete in idsToDelete)                        
   _mongoDbContext.ApiChildUsers.DeleteOne(Builders<ApiChildUsers>.Filter.Eq(u => u.Id, idToDelete)); 
  

Ответ №1:

вы могли бы попробовать следующий подход, при котором вы возвращаете идентификатор для сохранения и удаляете остальные следующим образом:

 var filter = Builders<ApiUsers>.Filter.Where(u => u.UserEMail == "test@test.com");
var projection = Builders<ApiUsers>.Projection.Expression(u=>u.Id);
var options = new FindOptions<ApiUsers, string> { Projection = projection, Limit = 1 };

var idToKeep = collection.FindSync(filter, options).ToList()[0];

collection.DeleteMany(
    u => u.UserEMail == "test@test.com" amp;amp;
         u.Id != idToKeep);
  

в качестве примечания я хотел бы предложить вам хранить идентификаторы на сервере как ObjectId вместо string, потому что это менее эффективно, поскольку для хранения ObjectId требуется всего 12 байт, что было бы меньше, чем его шестнадцатеричное строковое представление.

вот менее подробная тестовая программа, использующая mongodb.entities:

 using MongoDB.Entities;
using System.Threading.Tasks;

namespace TestApp
{
    public class ApiUsers : Entity
    {
        public string UserEMail { get; set; }
    }

    internal static class Program
    {
        private static async Task Main()
        {
            await DB.InitAsync("test", "localhost");

            await new[] {
                new ApiUsers { UserEMail = "test@test.com"},
                new ApiUsers { UserEMail = "test@test.com"},
                new ApiUsers { UserEMail = "test@test.com"},
                new ApiUsers { UserEMail = "teX@teX.com"},
            }.SaveAsync();

            var idToKeep = (await DB.Find<ApiUsers, string>()
                                    .Match(u => u.UserEMail == "test@test.com")
                                    .Project(u => u.ID)
                                    .Limit(1)
                                    .ExecuteAsync())[0];

            await DB.DeleteAsync<ApiUsers>(
                u => u.UserEMail == "test@test.com" amp;amp;
                     u.ID != idToKeep);
        }
    }
}