技.藝.道:elasticsearch常用搜索方法詳解

零、提要

1.簡單的搜索方式:query string search

2.強大的搜索方式:query DSL

3.搜索中的過濾:query filter

4.全文搜索:full-text search

5.部分內容搜索:phrase search

6.高亮搜索:highlight search

 

一、準備

環境準備:

見上一篇《技.藝.道:elasticsearch概念梳理及基礎操作

數據準備:

PUT /ecommerce/product/1

{

    "name" : "gaolujie yagao",

    "desc" : "gaoxiao meibai",

    "price" : 30,

    "producer" : "gaolujie producer",

    "tags" : ["meibai","fangzhu"]

}



PUT /ecommerce/product/2

{

    "name" : "jiajieshi yagao",

    "desc" : "youxiao meibai",

    "price" : 35,

    "producer" : "gaolujie producer",

    "tags" : ["meibai","fangzhu"]

}



PUT /ecommerce/product/3

{

    "name" : "zhonghua yagao",

    "desc" : "caoben meibai",

    "price" : 20,

    "producer" : "gaolujie producer",

    "tags" : ["qingxin"]

}



PUT /ecommerce/product/4

{

  "name":"heiren yagao",

  "desc":"heiren meibai",

  "price":50,

  "producer":"heiren yagao producer",

  "tags":["meibai"]

}

二、詳述

1.query string search

功能:實現簡單的條件搜索

基本語法:GET /yourindex/yourtype/_search

實例-搜索全部商品:GET /ecommerce/product/_search

條件查詢語法:GET /yourindex/yourtype/_search?q=name:yagao&sort=price:desc

實例-搜索name字段包含"yaogao"商品,結果按"price"字段倒序排列:GET /ecommerce/product/_search?q=name:yagao&sort=price:desc

查詢結果:


 

{

  "took": 2,

  "timed_out": false,

  "_shards": {

    "total": 5,

    "successful": 5,

    "failed": 0

  },

  "hits": {

    "total": 3,

    "max_score": 1,

    "hits": [

      {

        "_index": "ecommerce",

        "_type": "product",

        "_id": "2",

        "_score": 1,

        "_source": {

          "name": "jiajieshi yagao",

          "desc": "youxiao meibai",

          "price": 35,

          "producer": "gaolujie producer",

          "tags": [

            "meibai",

            "fangzhu"

          ]

        }

      },

      {

        "_index": "ecommerce",

        "_type": "product",

        "_id": "1",

        "_score": 1,

        "_source": {

          "name": "good gaolujie yagao",

          "desc": "gaoxiao meibai",

          "price": 30,

          "producer": "gaolujie producer",

          "tags": [

            "meibai",

            "fangzhu"

          ]

        }

      },

      {

        "_index": "ecommerce",

        "_type": "product",

        "_id": "3",

        "_score": 1,

        "_source": {

          "name": "zhonghua yagao",

          "desc": "caoben meibai",

          "price": 20,

          "producer": "gaolujie producer",

          "tags": [

            "qingxin"

          ]

        }

      }

    ]

  }

}

查詢結果說明:

  • took:本次查詢耗時(毫秒)
  • timed_out:是否超時,這裏是沒有
  • _shards:數據拆成了5個分片,所以對於搜索請求,會發送至所有primary shard(或者是它的某個replica shard也可以)
  • hits.total:查詢結果的數量,3個document。
  • hits.hits:包好了匹配搜索的document的詳細數據。

2.query DSL(Domain Specified Language)

功能:實現複雜的條件搜索

查詢所有數據:

GET /ecommerce/product/_search

{

"query": {"match_all" : {} }

}

查詢“name”字段包含“yagao”的數據,結果按“price”字段的值正序排列:

GET /ecommerce/product/_search
{
	"query" : {
		"match" : {
			"name" : "yagao"
		}
	},
	"sort" : [
	  {
		  "price":"asc"
	  }
	]
}

 

範圍查詢:

實例:

GET /ecommerce/product/_search
{
	"query" :  {"match_all" : {} },
	"from" : 1,
	"size" : 2
}

查詢指定字段:

GET /ecommerce/product/_search
{
	"query": {"match_all" : {} },
	"_source":["name","price"]
}

 

3.query filter

功能:實現數據過濾

查詢出價格高於25的數據:

GET /ecommerce/product/_search
{
	"query" : {
		"bool" : {
			"must" : {
				"match" : {
					"name" : "yagao"
				}
			},
			"filter": {
				"range":{
					"price" : {"gt":30}
				}
			}
		}
	}
}

 

4.full-text search

功能:實現全文檢索,即:只要“producer”字段中包含 yagao或producer都會被搜索出來,也就是說“部分匹配”的對象會被搜索到。

GET /ecommerce/product/_search
{
	"query":{
		"match" : {
			"producer":"yagao producer"
		}
	}
}

 

結果說明:

max_score:本次查詢結果中最高的匹配度

hits.hits._score:具體數據的匹配度

5.phrase search

功能:短語匹配搜索,即:只有當對象的指定字段包含完整關鍵詞時,纔會被搜索出來。

跟全文檢索相反,全文檢索會將輸入的搜索穿拆散開,去倒排索引裏面去一一匹配,只要能夠匹配上任意一個拆解後的單詞,就可以作爲結果返回phrase search

要求輸入的搜索串,必須在指定的字段文本中,完全包含一模一樣的,纔可以算匹配,才能作爲結果返回。

GET /ecommerce/product/_search
{
	"query":{
		"match_phrase":{
			"producer":"yagao producer"
		}
	}
}

 

6.highlight search

功能:搜索結果高亮顯示

GET /ecommerce/product/_search
{
	"query":{
		"match" : {
			"producer":"producer"
		}
	},
	"highlight":{
		"fields" : {
			"producer" : {}
		}
	}
}

看到你的輸出發現並沒有哪裏是高亮的對吧?難道是自己語句寫錯了?別擔心,如果你的輸出沒有報“error”,只是沒有高亮顯示,那麼你寫的沒錯,因爲這裏的高亮,指的是輸出的內容再html中是高亮顯示的,即只是將輸出結果中的關鍵詞放到了一個<em>關鍵詞</em>中。

輸出:

{

  "took": 29,

  "timed_out": false,

  "_shards": {

    "total": 5,

    "successful": 5,

    "failed": 0

  },

  "hits": {

    "total": 4,

    "max_score": 0.25811607,

    "hits": [

      {

        "_index": "ecommerce",

        "_type": "product",

        "_id": "1",

        "_score": 0.25811607,

        "_source": {

          "name": "good gaolujie yagao",

          "desc": "gaoxiao meibai",

          "price": 30,

          "producer": "gaolujie producer",

          "tags": [

            "meibai",

            "fangzhu"

          ]

        },

        "highlight": {

          "producer": [

            "gaolujie <em>producer</em>"

          ]

        }

      },

      {

        "_index": "ecommerce",

        "_type": "product",

        "_id": "3",

        "_score": 0.25811607,

        "_source": {

          "name": "zhonghua yagao",

          "desc": "caoben meibai",

          "price": 20,

          "producer": "gaolujie producer",

          "tags": [

            "qingxin"

          ]

        },

        "highlight": {

          "producer": [

            "gaolujie <em>producer</em>"

          ]

        }

      },

      {

        "_index": "ecommerce",

        "_type": "product",

        "_id": "2",

        "_score": 0.1805489,

        "_source": {

          "name": "jiajieshi yagao",

          "desc": "youxiao meibai",

          "price": 35,

          "producer": "gaolujie producer",

          "tags": [

            "meibai",

            "fangzhu"

          ]

        },

        "highlight": {

          "producer": [

            "gaolujie <em>producer</em>"

          ]

        }

      },

      {

        "_index": "ecommerce",

        "_type": "product",

        "_id": "4",

        "_score": 0.14638957,

        "_source": {

          "name": "heiren yagao",

          "desc": "heiren meibai",

          "price": 50,

          "producer": "heiren yagao producer",

          "tags": [

            "meibai"

          ]

        },

        "highlight": {

          "producer": [

            "heiren yagao <em>producer</em>"

          ]

        }

      }

    ]

  }

}

7.倒排索引

倒排索引的意義在於“按詞找文”,它是全文搜索的基礎。

什麼是倒排索引:

爲了搞清什麼是倒排索引,我們分步推演。

首先什麼是索引?

我不能說索引是什麼,可是我可以說它像什麼。它就像是一本書的目錄。我們看着目錄就知道自己想看的內容在哪一頁了。所以,索引的目的是讓我們更快找到對象的工具。爲了實現這種功能,有很多經典的實現,比如B樹索引,唯一索引等等。就像一本書的目錄也需要印在紙上,因此一本添加了目錄的書會佔用更多的書頁。同理,在數據庫中,一個有索引的表會佔用更多的存儲空間。也就是拿空間換時間。消耗更多的空間資源,節約更多的搜索時間。

倒排索引:

A數據的words字段的值:hello today dog cat

B數據的words字段的值:boby free hello fish

C數據的words字段的值:shell today hello

D數據的words字段的值:hi fish

===>

words字段的值中的詞

在哪個數據出現過

hello

A,B,C

today

A,C

dog

A

cat

A

boby

B

free

B

fish

B,D

shell

C

hi

D

 

好理解嗎?

再直白一點,我來講個故事。

那是去年冬天的一個深夜,我們產品需要上線,於是我們就很自然的加了班。那天很冷,經理決定請大家吃夜宵,看了一下這麼晚只有燒烤了。於是我們決定叫點燒烤擼一擼,於是開始點菜。

小張說:我要茄子,土豆,平菇,大魷魚,羊肉,水餃

小李說:我要韭菜,年糕,羊肉,土豆,豬腰子,水餃

小王說:我要五花肉,大魷魚,年糕,羊肉,牛肉

經理說:好的,我要茄子,年糕,羊肉,餛飩。

於是經理整理一下大家的菜單,怕直接發過去,老闆給弄錯了。於是得到下面這份訂單:

菜品

點餐人

茄子

小張,經理

土豆

小張,小李

平菇

小張

大魷魚

小張,小王

羊肉

小張,小李,小王,經理

水餃

小張,小李

韭菜

小李

年糕

小李,小王,經理

豬腰子

小李

五花肉

小王

牛肉

小王

餛飩

經理

對,就是這樣,假裝我就是吃混沌那個!

簡單的說就是:

正排索引:按文找詞

倒排索引:按詞找文

小結:方法很多,根據場景適時用即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章