我应该在 C# 中使用 MongoDb 的什么过滤器定义?
What filter definition for MongoDb should I use in C#?
想象一下这种情况:
我有一个名为 Filter 的实体,其中:
string Text { get; set; }
string State { get; set; }
所以在我的 Mongo collection 我有这个文档(过滤器):
{
"id" : "1",
"State" : "333",
"Text" : "SD"
},
{
"id" : "2",
"State" : "444",
"Text" : "X"
}
现在我有一个服务,它应该 return 所有文档与文本和状态的匹配。
所以想象一下我的服务收到一个 IEnumerable<string> texts
和一个 IEnumerable<string> states
具有以下值:
"states" : ["333","444"],
"texts" : ["SD"]
服务应该 return []
因为没有 state "333" 和 state "444" 的过滤器 与 text "SD" 同时出现。只有 return 如果我的 collection 有这个文件,它才会有结果:
{
"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;
}
但对于我的示例案例,这段代码 return 的响应是:
{
"id" : "1",
"State" : "333",
"Text" : "SD"
}
什么时候应该是 []
正如我之前所说。
有没有办法解决这种情况?谢谢。
我正在使用 ASP.NET Core 2.0 和 MongoDb.Driver 2.5.0.
您可以指定预期过滤器列表,然后使用如下所示的 $or
查询,在您获得 return 结果之前,您需要检查预期过滤器的长度是否与 return编辑结果。
在 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>();
}
想象一下这种情况:
我有一个名为 Filter 的实体,其中:
string Text { get; set; }
string State { get; set; }
所以在我的 Mongo collection 我有这个文档(过滤器):
{
"id" : "1",
"State" : "333",
"Text" : "SD"
},
{
"id" : "2",
"State" : "444",
"Text" : "X"
}
现在我有一个服务,它应该 return 所有文档与文本和状态的匹配。
所以想象一下我的服务收到一个 IEnumerable<string> texts
和一个 IEnumerable<string> states
具有以下值:
"states" : ["333","444"],
"texts" : ["SD"]
服务应该 return []
因为没有 state "333" 和 state "444" 的过滤器 与 text "SD" 同时出现。只有 return 如果我的 collection 有这个文件,它才会有结果:
{
"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;
}
但对于我的示例案例,这段代码 return 的响应是:
{
"id" : "1",
"State" : "333",
"Text" : "SD"
}
什么时候应该是 []
正如我之前所说。
有没有办法解决这种情况?谢谢。
我正在使用 ASP.NET Core 2.0 和 MongoDb.Driver 2.5.0.
您可以指定预期过滤器列表,然后使用如下所示的 $or
查询,在您获得 return 结果之前,您需要检查预期过滤器的长度是否与 return编辑结果。
在 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>();
}