使用ElasticSearch进行高级搜索

时间:2014-08-19 10:45:36

标签: php elasticsearch

我用PHP创建了一个小应用程序,我使用ES。 我的要求很好,但我得到了很好的结果。 我的请求看起来像:

  

链接:9200 /索引/ _search从= 0&安培;大小= 130安培; Q =尝试:?'是'   %2Bbrand:' BMW' %2B模型:' SERIE 5' %2Bprice:[500至700000]

当我发送此查询时,ES回复我的模型' SERIE 3'和#SERIE 5',它很棒,但是当我发送这个查询时,我想只收回'宝马'和' SERIE 5'。

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

首先,您应该看一下文档,以便更熟悉这些概念(analyze / difference between query and filters),这对于充分利用ElasticSearch非常重要。您可以找到一个很好的入门文档here

你的问题是你的"型号" field是一个字符串,默认情况下使用标准分析器进行分析。

由于模型名称中的空格,它会输出2个标记,如果您使用_analyze端点,则可以看到:

GET _analyze?analyzer=standard&text='Serie 5'

{
   "tokens": [
      {
         "token": "serie",
         "start_offset": 1,
         "end_offset": 6,
         "type": "<ALPHANUM>",
         "position": 1
      },
      {
         "token": "5",
         "start_offset": 7,
         "end_offset": 8,
         "type": "<NUM>",
         "position": 2
      }
   ]
}

除此之外,您还在使用查询,但会返回与甚至部分匹配的所有结果。所以,你在结果中确实拥有两辆车,但是&#34; SERIE 5&#34;汽车必须是第一个(因为它匹配得更好)而不是汽车&#34; SERIE 3&#34;,它由更高的 _score 属性表示。

您需要使用term filter,它只会返回包含您提供的字词值的文档。 但是,由于它适用于术语,您必须将字段的映射更改为&#34; not_analyzed&#34;像这样保持原样:

PUT /test/car/_mapping
{
    "properties":{
        "model":{
            "type": "string",
            "index":"not_analyzed"
        }
    }
}

最后,搜索请求将是这样的(价格标准为range filter,并使用and过滤器将两者结合起来):

GET /test/car/_search
{
    "query": {
        "filtered": {
           "filter": {
               "and": {
                  "filters": [
                     {
                     "term": {
                          "model": "Serie 3"
                       }
                     },
                     {
                         "range": {
                            "price": {
                               "from": 500,
                               "to": 70000
                            }
                         }
                     }
                  ]
               }
           }
        }
    }
}

答案 1 :(得分:0)

您的查询(url_decoded)看起来像

link:9200/index/_search?from=0&size=130&q=try:'yes' +brand:'BMW' +model:'SERIE 5' +price:[500 TO 700000]

我认为您正在使用'+',因此它正在为您的查询执行操作, 如果您想使用try:yesbrand:BMWmodel:SERIE 5,则必须通过AND关键字加入这些查询。

等。

link:9200/index/_search?from=0&size=130&q=try:'yes' 
AND brand:'BMW' AND model:'SERIE 5' AND price:[500 TO 700000]

你应该知道choosing analyzer(在字段的映射中),以便根据需要对事物编制索引。

它会工作,谢谢

Reference