当前位置: 首页 > 知识库问答 >
问题:

Elasticsearch:使用关键字标记器索引字段,但不使用stopwords

刘琨
2023-03-14

我正在寻找一种方法来搜索公司名称与关键字标记,但没有停止词。

例如:索引公司名称为“Hansel und Gretel Gmbh”

这里“und”和“Gmbh”是公司名称的停止词。

如果搜索项是"Hansel Gretel",则应找到该文档;如果搜索项是"Hansel",则不应找到任何文档。如果搜索词是"hansel gmbh",也应该找到no文档。

我曾尝试将关键字标记器与自定义分析器中的停止词相结合,但它没有工作(正如预期的那样,我猜)。

我也尝试过使用常用术语查询,但汉塞尔开始击中(再次如预期的那样)

提前谢谢。

共有1个答案

施振海
2023-03-14

有两种方式坏和丑。第一个使用正则表达式来删除停止词和修剪空格。有很多缺点:

  • 您必须支持空白符号化(regexp(/s))和特殊符号(。,;)移除您自己的
  • 不支持突出显示-关键字令牌不支持
  • 案件敏感性也是个问题
  • 规范化器(关键字分析器)是实验性的特征-坏的支持,没有特征

下面是一个循序渐进的示例:

curl -XPUT "http://localhost:9200/test" -H 'Content-Type: application/json' -d'
{
  "settings": {
    "analysis": {
      "normalizer": {
        "custom_normalizer": {
          "type": "custom",
          "char_filter": ["stopword_char_filter", "trim_char_filter"],
          "filter": ["lowercase"]
        }
      },
      "char_filter": {
        "stopword_char_filter": {
          "type": "pattern_replace",
          "pattern": "( ?und ?| ?gmbh ?)",
          "replacement": " "
        },
        "trim_char_filter": {
          "type": "pattern_replace",
          "pattern": "(\\s+)$",
          "replacement": ""
        }
      }
    }
  },
  "mappings": {
    "file": {
      "properties": {
        "name": {
          "type": "keyword",
          "normalizer": "custom_normalizer"
        }
      }
    }
  }
}'

现在我们可以检查我们的分析器是如何工作的(请注意,对规范化分析器的请求仅在ES 6. x中支持)

curl -XPOST "http://localhost:9200/test/_analyze" -H 'Content-Type: application/json' -d'
{
  "normalizer": "custom_normalizer",
  "text": "hansel und gretel gmbh"
}'

现在,我们准备为文档编制索引:

curl -XPUT "http://localhost:9200/test/file/1" -H 'Content-Type: application/json' -d'
{
  "name": "hansel und gretel gmbh"
}'

最后一步是搜索:

curl -XGET "http://localhost:9200/test/_search" -H 'Content-Type: application/json' -d'
{
    "query": {
        "match" : {
            "name" : {
                "query" : "hansel gretel"
            }
        }
    }
}'

另一种方法是:

  • 使用停止字过滤器创建标准文本分析器
  • 使用分析筛选出所有停止词和特殊符号
  • 手动连接令牌
  • 将术语作为关键字发送到ES

下面是一个循序渐进的示例

curl -XPUT "http://localhost:9200/test" -H 'Content-Type: application/json' -d'
{
  "settings": {
    "analysis": {
      "analyzer": {
        "custom_analyzer": {
          "type":      "custom",
          "tokenizer": "standard",
          "filter": ["lowercase", "custom_stopwords"]
        }
      }, "filter": {
        "custom_stopwords": {
          "type": "stop",
          "stopwords": ["und", "gmbh"]
        }
      }
    }
  },
  "mappings": {
    "file": {
      "properties": {
        "name": {
          "type": "text",
          "analyzer": "custom_analyzer"
        }
      }
    }
  }
}' 

现在我们准备分析我们的文本:

POST test/_analyze
{
  "analyzer": "custom_analyzer",
  "text": "Hansel und Gretel Gmbh."
}

结果如下:

{
  "tokens": [
    {
      "token": "hansel",
      "start_offset": 0,
      "end_offset": 6,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "gretel",
      "start_offset": 11,
      "end_offset": 17,
      "type": "<ALPHANUM>",
      "position": 2
    }
  ]
}

最后一步是令牌连接:hansel gretel。唯一的缺点是使用自定义代码进行手动分析。

 类似资料:
  • 问题内容: 我是Elasticsearch的新手,正在尝试使用和字段创建多字段索引。有了这些字段,它们都工作得很好,但是当我尝试在数组中获取一些结果时,它返回一个空的数组。 我的资料: 对应: 搜索: 期望: 按,或搜索,应返回结果 搜索应返回结果 搜索应返回结果 搜索依据不应返回结果 我想念什么? 问题答案: Cross_fields具有约束,所有字段应具有相同的搜索分析器,或者所有查询项应出现

  • 我正在尝试使用一个字段,只是为了复制的目的,而不是用下面的映射来索引它自己 但正在获取异常

  • 如何告诉Elasticsearch在按术语搜索时排除某个字段? 当一个普通用户搜索摩托车时,什么都不应该返回,但如果他们搜索史密斯,这两个都应该返回。 有能力搜索认证字段的用户如果搜索摩托车将返回标记,如果搜索史密斯将返回标记。

  • 问题内容: 如果我在一个类中有以下声明,其中是抽象类型: 是否能让我仍然能够更改中的对象的状态,但阻止我将新对象添加到列表中?如果我写错了,请您解释一下正在做什么以及何时应该使用关键字。 问题答案: 不,final关键字不会使列表或其内容不可变。如果您想要一个不可变的列表,则应使用: final关键字的作用是防止您为’synapses’变量分配新值。即,您不能写: 但是,您可以编写:

  • 我试图用_analyze API获得关键字标记的多字同义词。API对单字同义词返回预期结果,但对多字同义词不返回预期结果。以下是我的设置和分析链: 为什么analyze API不返回具有同义词类型的“foo bar”和“fooo bar”标记?

  • 我正在使用Spring Data ElasticSearch执行CRUD操作。默认情况下,当用@Document注释的POJO写入ElasticSearch索引时,索引字段名称与POJO的Java属性名称相同。如何将索引字段名称配置为不同的名称?例如,对于本文档POJO: 我如何配置它,使ElasticSearch中的索引字段被序列化为county_name而不是countyName?