imagine this situation:
I have a entity called Filter with:
string Text { get; set; }
string State { get; set; }
So in my Mongo collection I have this documents (filters):
{
"id" : "1",
"State" : "333",
"Text" : "SD"
},
{
"id" : "2",
"State" : "444",
"Text" : "X"
}
Now I have a service that it is supposed to return all the documents with the match of texts and states.
So imagine my service receives a IEnumerable<string> texts
and a IEnumerable<string> states
with this values:
"states" : ["333","444"],
"texts" : ["SD"]
And the service should return []
because there aren't Filters with state "333" and state "444" with text "SD" at the same time. It only should return Results if my collection had this documents:
{
"id" : "1",
"State" : "333",
"Text" : "SD"
},
{
"id" : "2",
"State" : "444",
"Text" : "SD"
}
Then the response would be:
{
"id" : "1",
"State" : "333",
"Text" : "SD"
},
{
"id" : "2",
"State" : "444",
"Text" : "SD"
}
My actual code to create my Filter Definition for this situation is:
private FilterDefinition<MyFilterEntity> CreateFilterForMyFilterEntity(IEnumerable<string> texts, IEnumerable<string> states)
{
var filterBuilder = Builders<MyFilterEntity>.Filter;
var filter = filterBuilder.Empty;
if (ListNotNullOrEmpty(texts))
{
filter = filter & filterBuilder.In(rf => rf.Text, texts);
}
if (ListNotNullOrEmpty(states))
{
filter = filter & filterBuilder.In(rf => rf.State, states);
}
return filter;
}
But for my example case this code returns the response:
{
"id" : "1",
"State" : "333",
"Text" : "SD"
}
when it should be []
as I said before.
Is there a way to solve this situation? Thank you.
I am using ASP.NET Core 2.0 with MongoDb.Driver 2.5.0.
You can specify a list of expected filters, then use $or
query like below and before you return results you need to check whether length of expected filters has the same value as length of returned results.
In MongoShell your query could look like this:
db.Filter.find(
{
$or: [
{ State: "333", Text: "SD" },
{ State: "444", Text: "SD" }
]
}
)
And your C# logic could be like below:
var states = new[] { "333", "444" };
var texts = new[] { "SD" };
var expectedNumberOfResults = states.Length * texts.Length;
IEnumerable<FilterClass> result;
var filters = from state in states
from text in texts
select Builders<FilterClass>.Filter.Where(f => f.Text == text && f.State == state);
FilterDefinition<FilterClass> q = Builders<FilterClass>.Filter.Or(filters);
var query = collection.Find(q);
if(query.Count() == expectedNumberOfResults)
{
result = query.ToList();
}
else
{
result = Enumerable.Empty<FilterClass>();
}