当前位置: 首页 > 面试题库 >

如果查询在引号之间,如何从elasticsearch获取精确的文本匹配

吕翰飞
2023-03-14
问题内容

我使用php对二进制文档(fscrawler)实现了elasticsearch。使用默认设置就可以正常工作。我可以在文档中搜索所需的单词,并且得到的结果不区分大小写。但是,我现在要进行精确匹配,即在当前搜索的顶部,如果查询用引号引起来,我想获得仅与查询完全匹配的结果。

我的映射如下所示:

"settings": {
"number_of_shards": 1,
"index.mapping.total_fields.limit": 2000,
"analysis": {
  "analyzer": {
    "fscrawler_path": {
      "tokenizer": "fscrawler_path"
    }
  },
  "tokenizer": {
    "fscrawler_path": {
      "type": "path_hierarchy"
    }
  }
}
.
.
.
  "content": {
    "type": "text",
    "index": true
  },

我对文档的查询如下所示:

    if ($q2 == '') {
    $params = [
        'index' => 'trial2',
        'body' => [
            'query' => [
                'match_phrase' => [
                        'content' => $q
                ]
            ]
        ]
    ];

    $query = $client->search($params);
    $data['q'] = $q;
}

对于完全匹配(无效):

    if ($q2 == '') {
        $params = [
            'index' => 'trial2',
            'body' => [
                'query' => [
                    'filter' =>[
                        'term' => [
                            'content' => $q
                        ]
                    ]
                ]
            ]
        ];

        $query = $client->search($params);
        $data['q'] = $q;
    }

内容字段是文档的主体。如何在内容字段中实现特定单词或短语的完全匹配?


问题答案:

content我了解,您的字段会很大,因为许多文档可能超过2-3 MB,这是很多话。

keyword根据您之前提到的问题的答案,使用字段来进行完全匹配毫无意义keyword 仅当数据结构化时,才
应使用keyword数据类型进行完全匹配
__

我了解的是content您所拥有的领域是无组织的。在这种情况下,您可能想在您的字段上使用Whitespace
Analyzer
content

另外,对于精确的词组匹配,您还可以查看“
匹配词组”查询。

以下是满足您的用例的示例索引,文档和查询。

对应:

PUT mycontent_index
{
  "mappings": {
    "properties": {
      "content":{
        "type":"text",
        "analyzer": "whitespace"            <----- Note this
      }
    }
  }
}

样本文件:

POST mycontent_index/_doc/1
{
  "content": """
      There is no pain you are receding
      A distant ship smoke on the horizon
      You are only coming through in waves
      Your lips move but I can't hear what you're saying
  """
}

POST mycontent_index/_doc/2
{
  "content": """          
      there is no pain you are receding
      a distant ship smoke on the horizon
      you are only coming through in waves
      your lips move but I can't hear what you're saying
  """
}

词组匹配:(按顺序搜索单词)

POST mycontent_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match_phrase": {                   <---- Note this for phrase match
            "content": "There is no pain"
          }
        }
      ]
    }
  }
}

匹配查询:

POST mycontent_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {                          <---- Use this for token based search
            "content": "there"
          }
        }
      ]
    }
  }
}

请注意,您的答复应相应。

要完全匹配一个单词,只需使用一个简单的Match查询即可。

请注意,当您不指定任何分析器时,默认情况下,ES使用标准分析器,这将导致将所有令牌转换为小写,然后再将它们存储在反向索引中。但是,Whitespace Analyzer
不会
将令牌转换为小写字母。结果Therethere它们作为两个不同的令牌存储在ES索引中。

我假设您了解Analysis和Analyzer的概念,如果不了解,建议您浏览链接,因为这将帮助您更多地了解我在说什么。

更新的答案:

了解您的要求后,您将无法在单个字段上应用多个分析器,因此基本上您有两个选择:

选项1: 使用多个索引

选项2:
在映射中使用多字段,如下所示:

这样,您的脚本或服务层将具有根据输入值推送到不同索引或字段的逻辑(一个具有双反逗号和一个简单令牌)。

多字段映射:

PUT <your_index_name>
{ 
   "mappings":{ 
      "properties":{ 
         "content":{ 
            "type":"text",                     <--- Field with standard analyzer
            "fields":{ 
               "whitespace":{ 
                  "type":"text",               <--- Field with whitespace
                  "analyzer":"whitespace"       
               }
            }
         }
      }
   }
}

理想情况下,我希望拥有第一个解决方案,即使用具有不同映射关系的多个索引,但是我强烈建议您重新审视用例,因为这在管理这样的查询中没有意义,但在您的调用中再无用处。

注意: 单节点集群是 您可能曾经做过的最糟糕的选择,特别是对于生产而言。

我建议您在一个单独的问题中详细说明文档数量,未来5年的增长率或类似情况,并且您的用例会比较繁琐或密集?其他团队可能也想利用这个集群吗?我建议您阅读更多内容,并与您的团队或经理讨论,以使您的方案更加清晰。

希望这可以帮助。



 类似资料:
  • 我使用php for binary documents(fscrawler)实现了elasticsearch。它在默认设置下工作得很好。我可以在文档中搜索我想要的单词,并得到不区分大小写的结果。然而,我现在想做精确匹配,即在当前搜索的顶部,如果查询被括在引号中,我想得到结果,只匹配查询完全…甚至区分大小写。 我的映射如下所示: 对于完全匹配(不起作用): 内容字段是文档的主体。如何实现内容字段中特

  • 我有一个索引(名称:“index1”)指向ElasticSearch中的多个文档。 文档的格式(json)是- 下面是映射- 我在ES查询中哪里做错了?

  • 问题内容: 我正在尝试编写一个NEST查询,该查询应基于完全匹​​配的字符串返回结果。我已经在网络上进行了研究,并且对使用术语,匹配,匹配短语有一些建议。我已经尝试了所有这些方法,但是搜索返回的结果中包含搜索字符串的一部分。例如,在我的数据库中,我有以下几行电子邮件地址: ter@gmail.com ter@hotmail.com terrance@hotmail.com 无论我是否使用: 要么

  • 问题内容: 我想在一个字段中搜索“ vision”项目,但是通过在DSL中使用match / match_phrace / term,我只得到了“ vision A”,“ vision B”,“ xx版本”,“ vision”等结果。 我想要的是精确匹配“视觉”应该获得最高分,而包含“视觉”的项目应该排在精确匹配之后。排名应该是: 我检查了Elasticsearch匹配精确术语其中识别出将“索引”

  • 在括号()之间获取文本的Reg表达式,我尝试过,但我没有得到RegEx。对于这个例子 例子:-

  • 问题内容: 所以我有一个字段以以下格式存储值:,例如23 / 2014、24 / 2014、12 / 2015等。 因此,如果将此字段映射为一个,则可以使用术语过滤器进行精确值搜索,如果我在该精确结构中搜索值(类似于1 / 2014、15 / 2014等),则可以正常工作,例如。 因此,使用11 /或/ 2014之类的其他内容进行搜索不会返回匹配。这可以。 但是,如果将字段定义为,则无法使用查询进