Home > Software engineering >  Using ElemMatch with FilterDefiniton by MongoDB Drive
Using ElemMatch with FilterDefiniton by MongoDB Drive

Time:11-03

I'm trying to search for a time interval by ElemMatch in C#. My fields of interest consist of simple objects or an arrays of objects, like the following:

  {
    "ID": "123456789",
    "field1": {
        "item1": "string",
        "item2": 123
    }
    "field2": [
        {
          "item11": 11.11,
          "myDatetime": {
             ts: 2022-10-23T23:14:55
           }
        },
        {
          "item11": 12.22,
          "myDatetime": {
             ts: 2022-08-23T23:14:55
           }
        }
     ]
  }

and my model is like:

public record MongoCollection
{
    public string ID { get; init; }
    public object field1 { get; init; }

    public List<object> field2 { get; init; }
}

I'm trying to deploy ElemMatch this way:

var filter = Builders<MongoCollection>.Filter.ElemMatch("field1",
  Builders<MongoCollection>.Filter.And(
    Builders<MongoCollection>.Filter.Gte("myDatetime.ts", fromDate),
    Builders<MongoCollection>.Filter.Lte("myDatetime.ts", tillDate))
);

The error that I receive on this part of code is:

Unable to cast object of type 'MongoDB.Bson.Serialization.Serializers.ObjectSerializer' to type 'MongoDB.Bson.Serialization.IBsonSerializer

I also tried this approach:

var field = new StringFieldDefinition<MongoCollection, List<object>>("field1");  

And

FieldDefinition<MongoCollection,List<object>> field = "field1";

And I put the field in ElemMatch like this:

var filter = Builders<MongoCollection>.Filter.ElemMatch(field,
  Builders<MongoCollection>.Filter.And(
    Builders<MongoCollection>.Filter.Gte("myDatetime.ts", fromDate),
    Builders<MongoCollection>.Filter.Lte("myDatetime.ts", tillDate))
);

and I received the same error. How can I solve it?

CodePudding user response:

  1. You should refer to field2 but not field1.

  2. As in the MongoCollection class the item in field2 is object type, the filter for the nested object should be in object type by using Builders<object>.

var filter = Builders<MongoCollection>.Filter.ElemMatch("field2",
    Builders<object>.Filter.And(
        Builders<object>.Filter.Gte("myDatetime.ts", fromDate),
        Builders<object>.Filter.Lte("myDatetime.ts", tillDate))
);

enter image description here

  • Related