将多个短语匹配到 Elastic Search 中的一个字段

Matching multiple phrases to one field in Elastic Search

我用 C# 构建了一个应用程序来搜索我的 Elasticsearch 文档,使用这段代码一切正常....

List<AuditLog> resultsList = Client.SearchAsync<AuditLog>(s => s
    .From(0)
    .Take(noRows)
    .Query(q => q
        .Bool(b => b
            .Must(mu => mu.MatchPhrase(mp => mp.Field("audit_Event").Query(auditEvents)),
                mu => mu.Match(ma => ma.Field(field).Query(value))
             )
          )
     )).Result.Documents.ToList();

一切正常,但有一个新要求,即针对多个短语搜索 audit_Event 字段,例如“用户登录”、“添加员工”等

我找到了对 multi_match 的引用,但这似乎与跨多个字段而不是一个字段中的多个值的搜索更相关。

根据下面的讨论,TermQuery 似乎可以完成这项工作,但 return 没有任何值。有什么想法吗?

QueryContainer queryAnd = new TermQuery() { Field = "audit_Application", Value = "MyApplication" };
QueryContainer queryOr = new TermQuery() { Field = "audit_Event", Value = "Employee Inserted" };
queryOr |= new TermQuery() { Field = "audit_Event", Value = "Employee Updated" }; 
QueryContainer queryMain = queryAnd & queryOr;

resultsList = Client.SearchAsync<AuditLog>(s => s
    .From(0)
    .Take(noRows)
    .Query(q => q
        .Bool(b => b
            .Must(queryMain)
        )
    )).Result.Documents.ToList();

我还使用 Kibana 检查了两个查询,第一个 return 的数据,但第二个没有,现在我想知道数据的索引方式是否有问题。 ..

GET auditlog/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match_phrase": {
            "audit_Event": "Employee Updated"
          }
        },
        {
          "match_phrase": {
            "audit_Event": "Employee Inserted"
          }
        }
      ]
    }
  }
}

GET auditlog/_search
{
  "query" : {
    "terms": {
        "audit_Event": ["Employee Updated","Employee Inserted"]
    }
  }
}

如果要将多个短语与单个字段匹配,则可以使用以下 bool query 与 match_phrase[=12= 的组合]

{
  "query": {
    "bool": {
      "must": [
        {
          "match_phrase": {
            "audit_Event": "User Login"
          }
        },
        {
          "match_phrase": {
            "audit_Event": "Add Employee"
          }
        }
      ]
    }
  }
}

请试试这个:

QueryContainer queryOr = new MatchPhraseQuery() { Field = "audit_Event", Query = "Employee Inserted" };
        queryOr |= new MatchPhraseQuery() { Field = "audit_Event", Query = "Employee Updated" };
        ISearchResponse<AuditLog> resultAuditLog = Client.Search<AuditLog>(s => s
                    .RequestConfiguration(r => r.DisableDirectStreaming())
                    .From(0)
                    .Size(100)
                    .Query(q2 => q2
                        .Bool(b => b
                        .Should(queryOr))
                    )
        );

根据您关于 OR 查询按预期工作的说法,下面是您可以使用 NEST 构建查询的方法。您可以根据需要进行任何特定的修改。

这段代码负责触发搜索调用

var searchDescriptor = new SearchDescriptor<AuditLog>()
    .Query(q => Blah(auditEventsList))
    .From(0)
    .Take(noRows);
    // other methods you want to chain here

var response = Client.searchAsync<AuditLog>(searchDescriptor);

此处生成搜索查询。请注意 SHOULD 的使用以及对负责动态生成 match_phrase 查询的另一个方法的调用。

private static QueryContainer Blah(List<string> auditEventsList)
{
    return new QueryContainerDescriptor<AuditLog>().Bool(
        b => b.Should(
            InnerBlah(auditEventsList)
        )
    );
}

此方法生成一个包含 match_phrase 个查询的数组,这些查询将传递给上述代码段中的 should。这些是通过迭代接收到的所有审计事件生成的。

private static QueryContainer[] InnerBlah(List<string> auditEventsList)
{
    QueryContainer orQuery = null;
    List<QueryContainer> queryContainerList = new List<QueryContainer>();
    foreach(var item in auditEventsList)
    {
        orQuery = new MatchPhraseQuery { Field = "audit_Event", Query = item };
        queryContainerList.Add(orQuery);
    }
    return queryContainerList.ToArray();
}