Home > database >  Query with filter builder on nested array using MongoDB C# driver with a given array of string
Query with filter builder on nested array using MongoDB C# driver with a given array of string

Time:10-15

Consider the following object structure stored as documents:

public class Foo
{
    public string Id { get; set; }
    public List<FooBar> Bars { get; set; }
    
    // ...
}
    
public class FooBar
{
    public string uid { get; set; }
    
    // ...
}

I have an array of strings :

var ArrayOfUid = ["STK-00112","STK-00117","STK-00113","STK-00114"] 

I want to get all the products where FooBar.uid in ArrayOfUid

So in the end I get the list of products like this without duplicates

on MongoDb Side query :

db.collection.find({
    "foobar.uid": {
    $in: [
        "STK-00113",
        "STK-00117",
        "STK-00113",
        "STK-00114"
        ]
    }
})

Is there a way to do it with the array of strings? At the moment I can achieve it with only one given string like this :

var findFluent = collection.Find(Builders<Foo>.Filter.ElemMatch(
    foo => foo.Bars, 
    foobar => foobar.uid == "STK-00113"));

This will return the object that has the

foobar.uid = "STK-00113"

Is there a way to go through the array of strings and return the list of all objects?

CodePudding user response:

You can set filter with BsonDocument object as below:

string[] uids = new string[] { "STK-00113", "STK-00117", "STK-00113", "STK-00114" };
FilterDefinition<Foo> filter = new BsonDocument(
    "foobar.uid", 
    new BsonDocument(
        "$in", 
        BsonArray.Create(uids)
    )
);
var findFluent = collection.Find(filter);

OR

Write MongoDB query and deserialize to BsonDocument.

var query = @"{
    'foobar.uid': {
      $in: [
        'STK-00113',
        'STK-00117',
        'STK-00113,
        'STK-00114'
      ]
    }
}";
var filter = MongoDB.Bson.Serialization.BsonSerializer.Deserialize<BsonDocument>(query);
var findFluent = collection.Find(filter);

FYI, you can use MongoDB Compass to export Query to C# Language.

CodePudding user response:

        var range = new[]
        {
            "STK-00113",
            "STK-00117",
            "STK-00113",
            "STK-00114"
        };

        var client = new MongoClient();
        var db = client.GetDatabase("d");
        var coll = db.GetCollection<Foo>("c");
        var filter = Builders<Foo>.Filter.Where(foo => foo.Bars.Any(b => range.Contains(b.uid)));
        var result = coll.Find(filter).ToList();

the generated query will be:

{
    "find": "c",
    "filter": {
        "Bars": {
            "$elemMatch": {
                "uid": {
                    "$in": ["STK-00113", "STK-00117", "STK-00113", "STK-00114"]
                }
            }
        }
    }
}
  • Related