弹性单字搜索问题

时间:2018-01-12 07:21:53

标签: elasticsearch

以下示例数据,我已插入索引...

"name":"Apple silicon cases for iPhone 6S Silver", "price":"100"
"name":"Apple silicon cases for iPhone 6S Gold", "price":"200"
"name":"Apple silicon cases for iPhone 6S Space Gray", "price":"300"
"name":"iPhone 8", "price":"70000"
"name":"iPhone 8 Plus", "price":"80000"
"name":"iPhone X", "price":"100000"
"name":"iPhone 8 Case, Black color", "price":"500"
"name":"iPhone battery charger", "price":"1000"

索引映射

{
  "shopfront": {
    "mappings": {
      "products": {
        "properties": {
          "name": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "price": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }
  }
}

当我运行以下查询...

POST shopfront/products/_search
{
  "query": {
    "match": {
      "name": "iphone"
    }
  }
}

我得到的结果是

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 8,
    "max_score": 0.2876821,
    "hits": [
      {
        "_index": "shopfront",
        "_type": "products",
        "_id": "3",
        "_score": 0.2876821,
        "_source": {
          "name": "Apple silicon cases for iPhone 6S Space Gray",
          "price": "300"
        }
      },
      {
        "_index": "shopfront",
        "_type": "products",
        "_id": "7",
        "_score": 0.19566216,
        "_source": {
          "name": "iPhone 8 Case, Black color",
          "price": "500"
        }
      },
      {
        "_index": "shopfront",
        "_type": "products",
        "_id": "5",
        "_score": 0.18232156,
        "_source": {
          "name": "iPhone 8 Plus",
          "price": "80000"
        }
      },
      {
        "_index": "shopfront",
        "_type": "products",
        "_id": "8",
        "_score": 0.18232156,
        "_source": {
          "name": "iPhone battery charger",
          "price": "1000"
        }
      },
      {
        "_index": "shopfront",
        "_type": "products",
        "_id": "1",
        "_score": 0.17068404,
        "_source": {
          "name": "Apple silicon cases for iPhone 6S Silver",
          "price": "100"
        }
      },
      {
        "_index": "shopfront",
        "_type": "products",
        "_id": "4",
        "_score": 0.16403349,
        "_source": {
          "name": "iPhone 8",
          "price": "70000"
        }
      },
      {
        "_index": "shopfront",
        "_type": "products",
        "_id": "6",
        "_score": 0.16403349,
        "_source": {
          "name": "iPhone X",
          "price": "100000"
        }
      },
      {
        "_index": "shopfront",
        "_type": "products",
        "_id": "2",
        "_score": 0.097333126,
        "_source": {
          "name": "Apple silicon cases for iPhone 6S Gold",
          "price": "200"
        }
      }
    ]
  }
}

我想要的是所有“iPhone”应该是最重要的&其余的事情应该在搜索列表的底部。

例如:

iPhone 8
iPhone 8 Plus
iPhone X
iPhone 8 Case, Black color
iPhone battery charger
Apple silicon cases for iPhone 6S Silver
Apple silicon cases for iPhone 6S Gold
Apple silicon cases for iPhone 6S Space Gray

“match_phrase_prefix”也在做任何帮助。任何想法,如何处理这种情况?

1 个答案:

答案 0 :(得分:0)

name.keyword字段上使用带有regexp should子句的布尔查询来提高以iPhone开头的条目的分数。

https://www.elastic.co/guide/en/elasticsearch/reference/6.1/query-dsl-bool-query.html

请注意,所有elasticsearch正则表达式查询都已锚定:

https://www.elastic.co/guide/en/elasticsearch/reference/6.1/query-dsl-regexp-query.html#_standard_operators

因此,iphone.*始终只与该行的开头匹配,并且不需要^与前面匹配。整体查询将如下所示:

{
    "query": {
        "bool" : {
            "should" : {
                "regexp" : {
                    "name.keyword" : "i[pP]hone [0-9X]( Plus)?"
                }
            },
            "must" : {
                 "match" : {
                     "name" : "iphone"
                }
            }
        }
    }
}