未找到短语时嵌套 ElasticSearch MatchPhrase 行为

Nest ElasticSearch MatchPhrase Behavior When Phrase Not Found

提问人:Guy 提问时间:9/27/2023 最后编辑:Guy 更新时间:9/27/2023 访问量:34

问:

使用 ElasticSearch Nuget 在名为 Message 的给定字段中搜索 Kibana 日志。

我想做什么

验证文本是否存在

我想在 Message 字段中搜索“Don't Find This”子字符串。 我想验证字符串是否不存在。

验证文本是否存在

我想在同一字段中搜索子字符串“Here it is”。 我验证它是否存在。

什么有效

使用 Match() 函数进行第二次测试成功。

什么不起作用

第一次测试失败。它返回了 10 条记录,因为它们似乎包含“Don't”或“Find”或“This”。

快速搜索表明我必须更改索引或创建自定义分析器,但我不明白这样做的影响,即它会对当前工作的测试产生什么影响?

在下面的代码中,我尝试了 MatchPhrase 而不是 Match

我很惊讶地发现,使用 MatchPhrase 导致最初有效的测试失败。

            ISearchResponse<LogRecord> searchResponse = await _elasticClient.SearchAsync<LogRecord>(s => s
                .AllIndices()
                .Query(q => q
                    .Bool(b => b
                        .Must(m =>
                        {
                            var mustClauses = new List<Func<QueryContainerDescriptor<LogRecord>, QueryContainer>>();

                            if (!string.IsNullOrEmpty(message))
                                mustClauses.Add(mc => mc.Match(m => m.Field(f => f.Message).Query(message)));
                           
// a list of other fields here...

                            mustClauses.Add(mc => mc.DateRange(dr => dr.Field(f => f.Time).GreaterThanOrEquals(startDate ?? DateTime.MinValue).LessThanOrEquals(endDate ?? DateTime.Now)));

                            return m.Bool(b1 => b1.Must(mustClauses));
                        })
                        )
                    )
                );
            return searchResponse;

我有一个 SpecFlow 功能文件,我在其中指定要验证的内容是存在还是不存在,如下所示:

    Then log has
        | Message                         |
        | some raw request before sending |
        | Start Blah Blah transaction      |  
        | sg_blahblah                      |
        | sg_Year                          |
        | sg_EmployeeNumber                |
    And log does not have
        | Message         | 
        | this_works_fine | 
        | this_works_too  |
        | No good         |

C# Elasticsearch 匹配 nest match-phrase

评论


答:

0赞 ktc 9/27/2023 #1

不太确定您的 DSL 需求。

如果我理解正确,它应该是这样的:

POST _search
{
  "query":{ 
    "bool": {
      "must": [
        {
          "match_phrase":{
            "my_message_field": "Message"
          }
        },
        {
          "match_phrase":{
            "my_message_field": "some raw request before sending"
          }
        },
        {
          "match_phrase":{
            "my_message_field": "Start Blah Blah transaction"
          }
        },
        {
          "match_phrase":{
            "my_message_field": "sg_blahblah"
          }
        },
        {
          "match_phrase":{
            "my_message_field": "sg_Year"
          }
        },
        {
          "match_phrase":{
            "my_message_field": "sg_EmployeeNumber"
          }
        }
      ],
      "must_not": [
        {
          "match_phrase":{
            "my_message_field": "Message"
          }
        },
        {
          "match_phrase":{
            "my_message_field": "this_works_too"
          }
        },
        {
          "match_phrase":{
            "my_message_field": "this_works_fine"
          }
        },
        {
          "match_phrase":{
            "my_message_field": "No good"
          }
        }
      ]
    }
  }
}

如果关键字只有 1 个单词,您还可以使用来提升性能;或“添加”以调整粒度(请参阅:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query-phrase.html)。filterslop

我全写了,因为在你的情况下,似乎会有很多带空格的关键词。match_phrase


然后将这些子句附加到您的 .match_phraseClauses

评论

0赞 Guy 9/27/2023
事实上,MatchPhrase 确实对我有用,只是等待更长的时间才能看到结果。
0赞 ktc 9/27/2023
根据数据结构、架构和场景,也许可以尝试以下方法:(a) 缩小索引范围而不是使用 .(b) 检查分片、路由策略;检查节点容量。(c) 用于将汇总数据转储到新的索引中,以改进未来的使用。(d) 调整映射/模板,使一些不太重要的数据成为 .(e) 从源头调整:添加更多标签对数据进行分类将使查询更容易、更快捷。AllIndices()transformkeyword