The following Entity is given:
public class MyClass
{
public MyClass()
{
Aliases= new List<string>();
}
public Guid Id { get; set; }
public string Name { get; set; }
public List<string> Aliases{ get; set; }
}
I want to search by name or by any matching alias using the following query:
Query.Or(
Query<MyClass>.Matches(a => a.Name, request.Name),
Query<MyClass>.ElemMatch(a => a.Aliases, query => query.Matches(alias => alias, request.Name))
)
This query works well as long as myClass.Aliases.Count > 0
! But as soon as its empty i get the following exception:
System.ArgumentNullException was unhandled by user code
HResult=-2147467261
Message=Value cannot be null.
Parameter name: name
Source=MongoDB.Driver
ParamName=name
StackTrace:
at MongoDB.Driver.Builders.Query.Matches(String name, BsonRegularExpression regex)
at MongoDB.Driver.Builders.QueryBuilder`1.Matches(Expression`1 memberExpression, BsonRegularExpression regex)
at My.Namespace.MyService.<>c__DisplayClassf.<Get>b__d(QueryBuilder`1 builder) in c:\Dev\....cs:line 148
at MongoDB.Driver.Builders.QueryBuilder`1.ElemMatch[TValue](Expression`1 memberExpression, Func`2 elementQueryBuilderFunction)
at MongoDB.Driver.Builders.Query`1.ElemMatch[TValue](Expression`1 memberExpression, Func`2 elementQueryBuilderFunction)
How can i workaround this limitation/bug?
ElemMatch
doesn't filter the results like a where clause, it only limits the array returned to one matching item, or none. You need to first filter the documents, and then limit the array inside it.
You should use Eq
like this:
Query.Or(
Query<MyClass>.EQ(a => a.Name, request.Name),
Query<MyClass>.EQ(a => a.Aliases, request.Name));
Lets assume that request.Name = "bar"
and the query should look like this:
{
"$or" : [
{
"Name" : "bar"
},
{
"Aliases" : "bar"
}]
}
MongoDB knows that Aliases is an array and it will "search" for the name and not "just compare"