Elasticsearch:使用关键字tokenizer索引字段,但没有停用词

时间:2018-01-04 14:12:18

标签: elasticsearch tokenize analyzer stop-words

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

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

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

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

我尝试在自定义分析器中将关键字标记符与停用词结合使用,但它没有用(正如我猜想的那样)。

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

提前致谢。

1 个答案:

答案 0 :(得分:1)

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

  • 你必须支持白空间标记化(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。唯一的缺点是使用自定义代码进行手动分析。