Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# MongoDB Driver - How to filter by arrays and a list of items

I want to perform a search on an array of strings and compare it to any string in a list of strings. For example:

This is the data structure:

{
    "CategoryIds": [ "A123", "B456", "C789" ]
}

and this is the search term:

List<string> search = new List<string> { "A123", "C789" };

I'm building my search query dynamically so I have these defined for start:

var builder = Builders<Item>.Filter;
ar filters = Builders<Item>.Filter.Empty;

I've tried all of the following approaches but none worked:

Using ElemMatch

filters &= builder.ElemMatch(i => i.CategoryIds, id => search.CategoryIds.Any(i => i.Equals(id)));

Using Intersect

filters &= builder.Where(i => search.CategoryIds.Intersect(i.CategoryIds).Any());

The only one that works is this one:

var categoryFilters = new List<FilterDefinition<Item>>();

foreach (string id in search.CategoryIds)
    categoryFilters.Add(builder.AnyEq(i => i.CategoryIds, id));

if (categoryFilters.Any())
    filters &= builder.Or(categoryFilters);

But it seems like overkill. Is there a simpler way to do that?

like image 501
Liran Friedman Avatar asked Oct 20 '25 03:10

Liran Friedman


1 Answers

  • To match a field containing an array of values against a single value, you need an AnyEq filter.
  • To match a single field value against multiple values, you need an In filter.
  • To compare a field containing an array of values against multiple values, you need a combination of both, namely an AnyIn filter:
var builder = Builders<Item>.Filter
filter = builder.AnyIn(item => item.CategoryIds, categoryIds)
like image 130
Avish Avatar answered Oct 21 '25 18:10

Avish



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!