skip to Main Content

In my mongodb, I have an array of objects that looks something like this.

[
 {
  _id: 123,
  info: [
         {
           name: John,
           random: ['31', 'food', 'sleep']
         }
        ]
 },
 {
  _id: 234,
  info: [
         {
           name: Amy,
           random: ['tv', 'food', 'sleep']
         }
        ]
 },
 {
  _id: 345,
  info: [
         {
           name: John,
           random: ['cars', 'tv31', 'sleep']
         }
        ]
 },
]

In C# how would I filter on info where name is John and random contains 31? I also don’t know what the difference is between the AnyIn vs In.

3

Answers


  1. in C# how would I filter on info where name is "John" and random contains "31"?

    You should be able to query the info property of each data item to filter your results, something like:

    var results = data.Where(item => 
        item.info.Any(info => 
            info.name == "John" && 
            info.random.Any(random => random == "31")));
    
    Login or Signup to reply.
  2. Following code works.

        public class Item
        {
            [BsonId]  
            [BsonRepresentation(BsonType.Int32)] 
            public int Id { get; set; }
            public IEnumerable<Person> info { get; set; }   
        }
    
        public class Person
        {
            public string name { get; set; }
            public List<string> random { get;set; }
    
        }
    
    var filter = Builders<Item>.Filter.Where(item => item.info.Any(info => (info.random.Any(random => random.Contains("31"))) && (info.name == "John")));
    var results = collection1.Find(filter).ToList();
    
    var results = collection1.AsQueryable()
                                    .Where(item => item.info.Any(info => (info.random.Any(random => random.Contains("31"))) && (info.name == "John")))
                                    .ToList();
    
    Login or Signup to reply.
  3. The LINQ query (which is covered by other answerers) works and is easier for those unfamiliar with the MongoDB Fluent query.


    For those who are looking for MongoDB Fluent syntax:

    Assume that your model classes are as below:

    public class RootModel
    {
       [BsonId]
       public int Id { get; set; }
    
       public InfoModel[] Info { get; set; }
    }
    
    [BsonNoId]
    public class InfoModel
    {
        public string Name { get; set; }
    
        public string[] Random { get; set; }
    }
    

    You should work with .ElemMatch and .AnyIn:

    var filter = Builders<RootModel>.Filter.ElemMatch(x => x.Info,
            Builders<InfoModel>.Filter.Eq(y => y.Name, "John")
            & Builders<InfoModel>.Filter.AnyIn(y => y.Random, new string[] { "31" }));
    

    For the Post Owner’s question on the differences between .In and .AnyIn:

    In works when your field is a single value and is used to match any element from the provided input array.

    AnyIn works when your field is an array and is used to match any element from the provided input array.


    Based on your scenario, you will get the syntax error when using .In, for the implementation of In as below:

    public FilterDefinition<TDocument> In<TField>(Expression<Func<TDocument, TField>> field, IEnumerable<TField> values)
    {
        return In(new ExpressionFieldDefinition<TDocument, TField>(field), values);
    }
    

    Unless you are checking the whole Random array that is exactly matched with the array, for example:

    random: {
       $in: [['31', 'food', 'sleep'], ...]
    }
    

    So this works with In:

    Builders<InfoModel>.Filter.In(y => y.Random, 
        new string[][] { new string[] { "31", "food", "sleep" } })
    

    That is another story matching the exact array value compared to the current question which asks for matching any element in the array.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search