我应该在 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>();
}