Home > Blockchain >  C# Mongo Filter Builder - nested array of objects - filter any docs where value of a specific proper
C# Mongo Filter Builder - nested array of objects - filter any docs where value of a specific proper

Time:06-11

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?

CodePudding user response:

I found it out by myself:

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

CodePudding user response:

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();
  • Related