使用语言分析器

Elasticsearch 的内置分析器都是全局可用的,不需要提前配置,它们也可以在字段映射中直接指定在某字段上:

  1. PUT /my_index
  2. {
  3. "mappings": {
  4. "blog": {
  5. "properties": {
  6. "title": {
  7. "type": "string",
  8. "analyzer": "english" (1)
  9. }
  10. }
  11. }
  12. }
  13. }

<1> title 字段将会用 english(英语)分析器替换默认的 standard(标准)分析器

当然,文本经过 english 分析处理,我们会丢失源数据:

  1. GET /my_index/_analyze?field=title (1)
  2. I'm not happy about the foxes

<1> 切词为: i'mhappiaboutfox

我们无法分辨源文档中是包含单数 fox 还是复数 foxes ;单词 not 因为是停用词所以被移除了,所以我们无法分辨源文档中是happy about foxes还是not happy about foxes,虽然通过使用 english(英语)分析器,使得匹配规则更加宽松,我们也因此提高了召回率,但却降低了精准匹配文档的能力。

为了获得两方面的优势,我们可以使用multifields(多字段)对 title 字段建立两次索引:一次使用english(英语)分析器,另一次使用 standard(标准)分析器:

  1. PUT /my_index
  2. {
  3. "mappings": {
  4. "blog": {
  5. "properties": {
  6. "title": { (1)
  7. "type": "string",
  8. "fields": {
  9. "english": { (2)
  10. "type": "string",
  11. "analyzer": "english"
  12. }
  13. }
  14. }
  15. }
  16. }
  17. }
  18. }

<1> 主 title 字段使用 standard(标准)分析器。

<2> title.english 子字段使用 english(英语)分析器。

替换为该字段映射后,我们可以索引一些测试文档来展示怎么在搜索时使用两个字段:

  1. PUT /my_index/blog/1
  2. { "title": "I'm happy for this fox" }
  3. PUT /my_index/blog/2
  4. { "title": "I'm not happy about my fox problem" }
  5. GET /_search
  6. {
  7. "query": {
  8. "multi_match": {
  9. "type": "most_fields", (1)
  10. "query": "not happy foxes",
  11. "fields": [ "title", "title.english" ]
  12. }
  13. }
  14. }

<1> 使用most_fields query type(多字段搜索语法来)让我们可以用多个字段来匹配同一段文本。

感谢 title.english 字段的切词,无论我们的文档中是否含有单词 foxes 都会被搜索到,第二份文档的相关性排行要比第一份高, 因为在 title 字段中匹配到了单词 not