Elasticsearch - 深刻搜索

结构化搜索

结构化搜索(Structured search) 是指有关探询那些具备内在结构数据的过程sql

在结构化查询中,咱们获得的结果 老是 非是即否,要么存于集合之中,要么存在集合以外。
结构化查询不关心文件的相关度或评分;它简单的对文档包括或排除处理。app

精确值查找

当进行精确值查找时, 咱们会使用过滤器(filters)。code

term 查询 数字

咱们首先来看最为经常使用的 term 查询, 能够用它处理数字(numbers)、布尔值(Booleans)、日期(dates)以及文本(text)。索引

  • 让咱们如下面的例子开始介绍,建立并索引一些表示产品的文档,文档里有字段 priceproductID价格产品ID ):
POST /my_store/products/_bulk
{ "index": { "_id": 1 }}
{ "price" : 10, "productID" : "XHDK-A-1293-#fJ3" }
{ "index": { "_id": 2 }}
{ "price" : 20, "productID" : "KDKE-B-9947-#kL5" }
{ "index": { "_id": 3 }}
{ "price" : 30, "productID" : "JODL-X-1937-#pV7" }
{ "index": { "_id": 4 }}
{ "price" : 30, "productID" : "QQPX-R-3956-#aD8" }

sql:查找具备某个价格的全部产品token

SELECT document FROM   products WHERE  price = 20

DSL:文档

GET /my_store/products/_search
{
 "query": {"term": {
   "price": {
     "value": "20"
   }
 }}
}

GET /my_store/products/_search
{
 "query": {
   "term": {
   "price": "20"
 }}
}

一般当查找一个精确值的时候,咱们不但愿对查询进行评分计算。只但愿对文档进行包括或排除的计算,因此咱们会使用 constant_score 查询以非评分模式来执行 term 查询并以一做为统一评分产品

GET /my_store/products/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "price": "20"
        }
      },
      "boost": 1.2
    }
  }  
}

term 查询 文本

sql:it

SELECT product FROM   products WHERE  productID = "XHDK-A-1293-#fJ3"

DSL:io

GET /my_store/products/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "productID": "XHDK-A-1293-#fJ3"
        }
      },
      "boost": 1.2
    }
  }
}

但这里有个小问题:咱们没法得到指望的结果。为何呢?问题不在 term 查询,而在于索引数据的方式,
若是咱们使用 analyze API (分析 API),咱们能够看到这里的 UPC 码被拆分红多个更小的 token.ast

GET /my_store/_analyze
{
  "field": "productID",
  "text": "XHDK-A-1293-#fJ3"
}

{
  "tokens" : [ {
    "token" :        "xhdk",
    "start_offset" : 0,
    "end_offset" :   4,
    "type" :         "<ALPHANUM>",
    "position" :     1
  }, {
    "token" :        "a",
    "start_offset" : 5,
    "end_offset" :   6,
    "type" :         "<ALPHANUM>",
    "position" :     2
  }, {
    "token" :        "1293",
    "start_offset" : 7,
    "end_offset" :   11,
    "type" :         "<NUM>",
    "position" :     3
  }, {
    "token" :        "fj3",
    "start_offset" : 13,
    "end_offset" :   16,
    "type" :         "<ALPHANUM>",
    "position" :     4
  } ]
}

这里有几点须要注意:

  • Elasticsearch 用 4 个不一样的 token 而不是单个 token 来表示这个 UPC 。
  • 全部字母都是小写的。
  • 丢失了连字符和哈希符( # )

因此当咱们用 term 查询查找精确值 XHDK-A-1293-#fJ3 的时候,找不到任何文档,由于它并不在咱们的倒排索引中,正如前面呈现出的分析结果,索引里有四个 token 。

为了不这种问题,咱们须要告诉 Elasticsearch 该字段具备精确值,要将其设置成 not_analyzed 无需分析的

DELETE /my_store 

PUT /my_store
{
  "mappings": {
    "products":{
      "properties": {
        "productID":{
          "type": "keyword"
        }
      }
    }
  }
}

GET /my_store/products/_search
{
    "query" : {
        "constant_score" : {
            "filter" : {
                "term" : {
                    "productID" : "XHDK-A-1293-#fJ3"
                }
            }
        }
    }
}

组合过滤器

SQL:

SELECT product
FROM   products
WHERE  (price = 20 OR productID = "XHDK-A-1293-#fJ3")
  AND  (price != 30)

DSL:

  • must
    全部的语句都 必须(must) 匹配,与 AND 等价。
  • must_not
    全部的语句都 不能(must not) 匹配,与 NOT 等价。
  • should
    至少有一个语句要匹配,与 OR 等价。
GET /my_store/products/_search
{
   "query" : {
            "bool" : {
              "should" : [
                 { "term" : {"price" : 20}}, 
                 { "term" : {"productID" : "XHDK-A-1293-#fJ3"}} 
              ],
              "must_not" : {
                 "term" : {"price" : 30} 
              }
           }
   }
}
相关文章
相关标签/搜索