想象一下这种情况:
我有一个名为过滤器的实体,其中包含:
string Text { get; set; }
string State { get; set; }
所以在我的Mongo系列中我有这些文件(过滤器):
{
"id" : "1",
"State" : "333",
"Text" : "SD"
},
{
"id" : "2",
"State" : "444",
"Text" : "X"
}
现在我有一项服务,它应该返回所有文本和状态匹配的文件。
想象一下,我的服务会收到IEnumerable<string> texts
和IEnumerable<string> states
这个值:
"states" : ["333","444"],
"texts" : ["SD"]
该服务应该返回[]
,因为没有州&#34; 333&#34; 和州&#34; 444&#34的过滤器; 同时使用文字&#34; SD&#34; 。如果我的收藏有这些文件,它只会返回结果:
{
"id" : "1",
"State" : "333",
"Text" : "SD"
},
{
"id" : "2",
"State" : "444",
"Text" : "SD"
}
然后回复是:
{
"id" : "1",
"State" : "333",
"Text" : "SD"
},
{
"id" : "2",
"State" : "444",
"Text" : "SD"
}
我为这种情况创建过滤器定义的实际代码是:
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;
}
但是对于我的示例,此代码返回响应:
{
"id" : "1",
"State" : "333",
"Text" : "SD"
}
如前所述,应该是[]
。
有没有办法解决这种情况?谢谢。
我正在使用ASP.NET Core 2.0和MongoDb.Driver 2.5.0。
答案 0 :(得分:1)
您可以指定预期过滤器的列表,然后使用$or
查询,如下所示,在返回结果之前,您需要检查预期过滤器的长度是否与返回结果的长度具有相同的值。
在MongoShell中,您的查询可能如下所示:
db.Filter.find(
{
$or: [
{ State: "333", Text: "SD" },
{ State: "444", Text: "SD" }
]
}
)
你的C#逻辑可能如下所示:
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>();
}