Elasticsearch:使用关键字标记器但不使用停用词对字段进行索引

标签 elasticsearch tokenize analyzer stop-words

我正在寻找一种使用关键字标记但不使用停用词来搜索公司名称的方法。

例如:索引的公司名称是“Hansel und Gretel Gmbh”。

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

如果搜索词是“Hansel Gretel”,则应该找到该文档, 如果搜索词是“Hansel”,则不应找到任何文档。如果搜索词是“hansel gmbh”,则也应该找不到任何文档。

我尝试在自定义分析器中将关键字标记器与停用词结合起来,但它不起作用(正如我猜测的那样)。

我也尝试过使用常用术语查询,但“Hansel”开始出现(再次如预期)

提前致谢。

最佳答案

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

  • 您必须支持自己删除空格标记化(regexp(/s+))和特殊符号(.,;)
  • 不支持突出显示 - 关键字标记器不支持
  • 区分大小写也是一个问题
  • normalizers (关键字分析器)是实验性功能 - 支持不佳,没有功能

这是分步示例:

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 支持对 Normalyzer 的请求)

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:使用关键字标记器但不使用停用词对字段进行索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48097075/

相关文章:

Elasticsearch : aggregation "existing" fields

c# - 需要为 C# 代码构建 XML 表示

ios - Xcode for iOS 项目的动态分析器和静态分析器有什么区别?

elasticsearch - 如果文本包含特殊字符(如#,@),则自定义标记生成器不会按预期生成标记

elasticsearch - 如何在Elasticsearch中更改字段数据类型

PHP ElasticSearch如何在索引记录之前设置映射?

Python - 分词、替换单词

python - 如何查找列表中句子列表中每个单词的引理和频率计数?

c# - Roslyn 分析器规则不会使构建失败

amazon-web-services - AWS Elastic Beanstalk 和 Docker - EXPOSE 至少需要一个参数