使用Elasticsearch的Google类型查询

时间:2015-12-16 02:40:45

标签: elasticsearch

假设我有以下文件:

{title:"Sennheiser HD 800"}

我希望所有这些查询都返回此文档。

  • senn
  • heise
  • sennheise
  • sennheiser
  • sennheiser 800
  • sennheiser hd
  • hd
  • 800 hd
  • hd ennheise

简而言之,我想找到一个或多个部分词。 在我的地图中我正在使用这个分析器

{
  "settings": {
    "analysis": {
      "analyzer": {
        "case_insensitive_sort": {
          "tokenizer": "keyword",
          "filter": [
            "lowercase"
          ]
        }
      }
    }
  }
}

和地图

{
  "title": {
    "type": "string",
    "fields": {
      "raw": {
        "type": "string",
        "index": "not_analyzed"
      },
      "lower_case_sort": {
        "type": "string",
        "analyzer": "case_insensitive_sort"
      }
    }
  }
}

并且查询是一个简单的字符串查询

{
  "query": {
    "query_string": {
      "fields": [
        "title.lower_case_sort"
      ],
      "query": "*800 hd*"
    }
  }
}

例如,此查询失败。

1 个答案:

答案 0 :(得分:3)

您需要ngrams

以下是我为Qbox撰写的一篇博文:

https://qbox.io/blog/an-introduction-to-ngrams-in-elasticsearch

(请注意,"index_analyzer"不再适用于ES 2.x;请改用"analyzer"; "search_analyzer"仍然可以使用。)

使用此映射(稍微修改了博客文章中的一个;我将在那里引用您的深入解释):

PUT /test_index
{
   "settings": {
      "analysis": {
         "filter": {
            "ngram_filter": {
               "type": "ngram",
               "min_gram": 2,
               "max_gram": 20
            }
         },
         "analyzer": {
            "ngram_analyzer": {
               "type": "custom",
               "tokenizer": "standard",
               "filter": [
                  "lowercase",
                  "ngram_filter"
               ]
            }
         }
      }
   },
   "mappings": {
      "doc": {
         "properties": {
            "title": {
               "type": "string",
               "analyzer": "ngram_analyzer",
               "search_analyzer": "standard"
            }
         }
      }
   }
}

索引您的文档:

POST /test_index/doc/1
{
   "title": "Sennheiser HD 800"
}

然后您列出的任何查询都可以使用以下格式:

POST /test_index/_search
{
   "query": {
      "match": {
         "title": {
            "query": "heise hd 800",
            "operator": "and"
         }
      }
   }
}

如果您只有一个学期,那么您就不需要"operator"部分:

POST /test_index/_search
{
   "query": {
      "match": {
         "title": "hd"
      }
   }
}

以下是我用来玩它的一些代码:

http://sense.qbox.io/gist/a9accf67f1713ca99819f45ce0ac28adaea691a9