skip to Main Content

I have a mongo collection (of <BsonDocument>) who could look like this:

{
  "someProperty1": "someValue1",
  "users": [
   { "name": "[email protected]", "displayName" : "Sample User" }
   { "name": "[email protected]", "displayName" : "Another User" }
  ]
},
  "someProperty2": "someValue2",
  "users": [
   { "name": "[email protected]", "displayName" : "Test User" },
   { "name": "[email protected]", "displayName" : "Another User" },
  ]
},
  "someProperty3": "someValue3",
  "users": [
   { "name": "[email protected]", "displayName" : "Another User" }
  ]
}

I want to filter with an IEnumerable of strings, that contains a set of name and want to get every document where at least one of the names in users is matching.

For example i would have Array filterArray with the following Value:

["[email protected]", "[email protected]"]

with this i want to build a FilterDefinition filter and after appling it:

await mongoColletion.Find(filter).ToListAsync()

It should have the following output (as IEnumerable<BsonDocument>):

[
  {
  "someProperty1": "someValue1",
  "users": [
     { "name": "[email protected]", "displayName" : "Sample User" }
     { "name": "[email protected]", "displayName" : "Another User" }
   ]
  },
  "someProperty2": "someValue2",
  "users": [
     { "name": "[email protected]", "displayName" : "Test User" },
     { "name": "[email protected]", "displayName" : "Another User" },
    ]
  }
]

How can I build this FilterDefinition?

2

Answers


  1. Chosen as BEST ANSWER

    I found it out by myself:

    var filter = Builders<BsonDocument>.Filter.AnyIn("users.name", filterArray);
    

  2. You can use $elemMatch and $in

    db.productList.find({
        users: {
            $elemMatch: { 
                name: {
                    $in: ['[email protected]', '[email protected]' ]
                }
            }
        }
    });
    

    In C#

    var coll = db.GetCollection<BsonDocument>("collection_name");
    var result = coll.Find("{ users: { $elemMatch: {name: { $in: ['[email protected]', '[email protected]' ] }  }  } }").ToList();
    

    Or with Builder

    List<string> list = new List<string>() { "[email protected]", "[email protected]" };
    var filter = Builders<BsonDocument>.Filter.ElemMatch("users",
            Builders<BsonDocument>.Filter.In("name", list));
    

    Or with data model:

    [BsonIgnoreExtraElements]
    public class Model
    {
        [BsonElement("users")]
        public User[] Users { get; set; }
    }
    
    public class User
    {
        [BsonElement("name")]
        public string Name { get; set; }
        [BsonElement("displayName")]
        public string DisplayName { get; set; }
    }
    

    You can use this filter with data model

    List<string> list = new List<string>() { "[email protected]", "[email protected]" };
    var filter = Builders<Model>.Filter.ElemMatch(m => m.Users, 
        Builders<User>.Filter.In(u => u.Name, list));
    var coll = db.GetCollection<Model>("collection_name");
    var result = coll.Find(filter).ToList();
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search