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

xzabzqsa  于 2023-10-17  发布在  ElasticSearch
关注(0)|答案(1)|浏览(95)

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

我想做什么

验证文本不存在

我想在消息字段中搜索“找不到此”子字符串。我想验证字符串是否不存在。

验证文本存在

我想在同一字段中搜索子字符串“Here it is”。我确认它存在。

什么工作

第二个测试使用Match()函数成功完成。

What Did Not Work

第一次测试失败了。它返回了10条记录,因为它们似乎包含“不要”或“查找”或“这个”。
快速搜索建议我必须更改索引或创建一个自定义分析器,但我不明白这样做的后果,即它对当前工作的测试有什么影响?
在下面的代码中,我尝试了 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         |
laik7k3q

laik7k3q1#

不太确定您的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"
          }
        }
      ]
    }
  }
}

如果关键字只有一个单词,您也可以使用filter来提高性能;或添加slop以调整粒度(请参见:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query-phrase.html)。
我写的所有在match_phrase,因为它似乎会有很多关键字与空格在您的情况。
然后将这些match_phrase子句附加到Clauses

相关问题