部分单词搜索 - ElasticSearch 1.7.2

时间:2015-10-09 11:44:36

标签: elasticsearch full-text-search

我一直在尝试使用ElasticSearch为应用程序构建搜索模块。下面是我从其他StackOverflow帖子中读取的示例代码构建的索引结构。

{
  "megacorp4":{
    "settings":{
      "analysis":{
        "analyzer":{
          "my_analyzer":{
            "type":"custom",
            "tokenizer":"my_ngram_tokenizer",
            "filter":[
              "my_ngram_filter"
            ]
          }
        },
        "filter":{
          "my_ngram_filter":{
            "type":"edgeNGram",
            "min_gram":3,
            "max_gram":15
          }
        },
        "tokenizer":{
          "my_ngram_tokenizer":{
            "type":"edgeNGram",
            "min_gram":3,
            "max_gram":15
          }
        }
      },
      "mappings":{
        "employee":{
          "properties":{
            "about":{
              "type":"string",
              "analyzer":"my_analyzer"
            },
            "age":{
              "type":"long"
            },
            "first_name":{
              "type":"string"
            },
            "interests":{
              "type":"string",
              "analyzer":"my_analyzer"
            },
            "last_name":{
              "type":"string"
            }
          }
        }
      }
    }
  }
}

以下是我为测试搜索功能而插入的记录

[
  {
    "first_name":"John",
    "last_name":"Smith",
    "age":25,
    "about":"I love to go rock climbing",
    "interests":[
      "sports",
      "music"
    ]
  },
  {
    "first_name":"Douglas",
    "last_name":"Fir",
    "age":35,
    "about":"I like to build album climb cabinets",
    "interests":[
      "forestry",
      "music"
    ]
  },
  {
    "first_name":"Jane",
    "last_name":"Smith",
    "age":32,
    "about":"I like to collect rock albums",
    "interests":[
      "music"
    ]
  }
]

我在'about'列上搜索,使用API​​(通过POSTMAN)和Python客户端,如下所示:

API查询:

localhost:9200/megacorp4/_search?q=climb

Python查询:

from elasticsearch import Elasticsearch
from pprint import pprint
es = Elasticsearch()
res = es.search(index="megacorp4", body={"query": {"match": {'about':"climb"}}})
pprint(res)

我只能获得完全匹配,并且我没有在输出中获得“攀爬”的结果。然而,当我在查询中用'climb *'替换'climb'时,我得到2条'攀爬'和'攀爬'的记录。我不想使用'*'通配符方法。

我也尝试过使用'英语','标准'和& 'ngram'内置分析仪,但似乎没有任何效果。

需要帮助才能实现将密钥搜索为全文中的部分单词。

提前致谢。

1 个答案:

答案 0 :(得分:0)

请改用此映射:

删除测试

PUT /test
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "my_ngram_filter"
          ]
        }
      },
      "filter": {
        "my_ngram_filter": {
          "type": "edgeNGram",
          "min_gram": 3,
          "max_gram": 15
        }
      }
    }
  },
  "mappings": {
    "employee": {
      "properties": {
        "about": {
          "type": "string",
          "analyzer": "my_analyzer"
        },
        "age": {
          "type": "long"
        },
        "first_name": {
          "type": "string"
        },
        "interests": {
          "type": "string",
          "analyzer": "my_analyzer"
        },
        "last_name": {
          "type": "string"
        }
      }
    }
  }
}

POST /test/employee/_bulk
{"index":{}}
{"first_name":"John","last_name":"Smith","age":25,"about":"I love to go rock climbing","interests":["sports","music"]}
{"index":{}}
{"first_name":"Douglas","last_name":"Fir","age":35,"about":"I like to build album climb cabinets","interests":["forestry","music"]}
{"index":{}}
{"first_name":"Jane","last_name":"Smith","age":32,"about":"I like to collect rock albums","interests":["music"]}

GET /test/_search?q=about:climb

GET /test/_search
{
  "query": {
    "query_string": {
      "query": "about:climb"
    }
  }
}

GET /test/_search
{
  "query": {
    "match": {
      "about": "climb"
    }
  }
}

两个变化:

  • 您需要settings部分
  • 的另一个结束花括号
  • 将您的自定义标记生成器(因为您已经拥有edgeNGram过滤器而无法帮助)替换另一个,我的建议是standard tokenizer

对于?q=climb部分,默认情况下会搜索使用_all分析器分析的standard字段,而不是您的自定义字段。

因此,正确的查询是localhost:9200/megacorp4/_search?q=about:climb