Конструктор фильтров выдает исключение в драйвере C# MongoDB

#c# #mongodb #mongodb-query #mongodb-.net-driver #mongodb-csharp-2.0

Вопрос:

Я пытаюсь извлечь документ из MongoDB с помощью драйвера c# mongo.

 public class Record
{
    [BsonId]
    public ObjectId Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Data { get; set; }
}
public class Name
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
var Names = new List<Names>;
Names.Add(new Name(FirstName = "abc", LastName = "xyz"));
Names.Add(new Name(FirstName = "123", LastName = "789"));
Names.Add(new Name(FirstName = "a1b2", LastName = "c7d8"));
 

Я попытался выполнить приведенный ниже запрос, чтобы отфильтровать и получить необходимый документ. Но этот запрос завершается ошибкой и создает исключение.

 FilterDefinition<Record> patentFilter = Builders<Record>.Filter.Where(y => Names.Any(x=> x.Name == y.Name amp;amp; x.LastName == y.LastName));
 

Исключение

 System.ArgumentException: 'Unsupported filter: Any(value(Name]).Where((({document}{FirstName} == {document}{FirstName}) AndAlso ({document}{LastName} == {document}{LastName})))).'
 

Комментарии:

1. исключение говорит о том, что такой фильтр не поддерживается типизированным способом, но вы все равно можете определить его как простой документ BsonDocument (вместо этого используя Builder) и передать его в свой метод вместо FilterDefinition

Ответ №1:

Опоздал с ответом.

Предложил бы:

  1. Генерировать nameFilters .

    Каждый nameFilter должен соответствовать равным ( $eq ) для обоих FirstName и ( $and ) LastName .

  2. Родительский фильтр ( filter ) связывает nameFilters с $or .

    Любой документ, который соответствует nameFilter требованиям, будет возвращен.

 var names = new List<Name>();
names.Add(new Name { FirstName = "abc", LastName = "xyz" });
names.Add(new Name { FirstName = "123", LastName = "789" });
names.Add(new Name { FirstName = "a1b2", LastName = "c7d8" });

List<FilterDefinition<Record>> namefilters = new List<FilterDefinition<Record>>();

foreach (var name in names)
{
    FilterDefinition<Record> namefilter = Builders<Record>.Filter.And(
        Builders<Record>.Filter.Eq(x => x.FirstName, name.FirstName),
        Builders<Record>.Filter.Eq(x => x.LastName, name.LastName)
    );

    namefilters.Add(namefilter);
}

FilterDefinition<Record> filter = Builders<Record>.Filter.Or(namefilters);

var filteredRecords = _collection.Find(filter)
    .ToList();
 

Запрос MongoDB

 db.collection.find({
  $expr: {
    $or: [
      {
        $and: [
          {
            $eq: [
              "$FirstName",
              "abc"
            ]
          },
          {
            $eq: [
              "$LastName",
              "xyz"
            ]
          }
        ]
      },
      // Other name filters
    ]
  }
})
 

Образец игровой площадки Монго