elasticsearch輕量搜索的那些事

前言
elasticsearch本身就是為搜索而生的組件,所以搜索才是它的重頭戲。從今天我們就學(xué)習es的各種檢索語法了,但是我大概看了下官方文檔,發(fā)現(xiàn)他對于各種檢索語法的解釋比較少,雖然也有好多示例,但是都比較零散,很難讓我們看清楚它的語法規(guī)則。因此,我們今天也不會有太多內(nèi)容分享,但是我這邊會花兩天時間梳理相關(guān)規(guī)則,爭取未來兩天整理出它的語法規(guī)則。
下面我們就先來看一些簡單的檢索規(guī)則。
elastsearch搜索
輕量搜索
這個檢索語法類似于我們傳統(tǒng)數(shù)據(jù)庫中不加條件的查詢語句,他會查詢megacorp索引下所有employee的數(shù)據(jù),然會返回
curl -X GET "localhost:9200/megacorp/employee/_search?pretty"
返回結(jié)果如下:
{
"took" : 78,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "megacorp",
"_type" : "employee",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"name" : "syske",
"age" : 25,
"about" : "I love to read book",
"interests" : [
"sports",
"music"
]
}
}
]
}
}
下面我們簡單解釋下搜索結(jié)果:
took:這個應(yīng)該搜索耗時時間,單位一般應(yīng)該是毫秒,在測試過程中我發(fā)現(xiàn)每次的返回結(jié)果都會都差異timed_out:請求是否超時_shards:分片,應(yīng)該和存儲有關(guān),類似于傳統(tǒng)數(shù)據(jù)存儲中的分庫分表,應(yīng)該就是存儲分割的單位。這里返回的是我們分片的匯總信息_shards.total:總分片數(shù)_shards.successful:這個應(yīng)該表示的是搜索到結(jié)果的分片數(shù)_shards.skipped:這個應(yīng)該表示未搜索到數(shù)據(jù)的分片數(shù)_shards.failed:那這個就表示搜索失敗的分片數(shù)了hits:這應(yīng)該就是我們搜索到的結(jié)果hits.total:主要存放返回結(jié)果匯總信息hits.total.value:查詢到的結(jié)果數(shù)量hits.total.relation:查詢結(jié)果的關(guān)系,eq表示相等(應(yīng)該是equals的簡寫),那ne應(yīng)該就表示不相等,目前沒找到官方給的說明,網(wǎng)上也沒有比較靠譜的解釋。hits.max_score:返回結(jié)果中score的最大值,這個score應(yīng)該表示匹配度,因為沒有文檔,所以暫時只能推測hits.hits:這個就是最終的搜索結(jié)果了,所有的匹配結(jié)果都會在這里面顯示。這底下的數(shù)據(jù)也和我們get返回的結(jié)果很類似。hits.hits._index:索引hits.hits._type:數(shù)據(jù)類型hits.hits._id:數(shù)據(jù)idhits.hits._score:這個就是我們剛說的匹配度hits.hits._source:最終的搜索結(jié)果
根據(jù)關(guān)鍵字搜索
相比于前面的那種查詢?nèi)?,這種方式查詢就比較靈活了,我們可以根據(jù)數(shù)據(jù)中的某個字段名進行查詢,具體語法如下:
索引/數(shù)據(jù)類型/_search?q=字段名:字段值下面是搜索樣例:
curl -X GET "localhost:9200/megacorp/employee/_search?q=name:syske&pretty"返回結(jié)果如下:
{
"took" : 6,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "megacorp",
"_type" : "employee",
"_id" : "1",
"_score" : 0.2876821,
"_source" : {
"name" : "syske",
"age" : 25,
"about" : "I love to read book",
"interests" : [
"sports",
"music"
]
}
}
]
}
}具體返回結(jié)果如下:

查詢不到結(jié)果時,返回結(jié)果如下:

查詢表達式搜索
Elasticsearch提供一個豐富靈活的查詢語言叫做 查詢表達式 , 它支持構(gòu)建更加復(fù)雜和健壯的查詢。領(lǐng)域特定語言 (
DSL), 使用JSON構(gòu)造了一個請求。查詢語法也基本上和我們前面的查詢一致,唯一的區(qū)別是,表達式搜索的時候,需要傳一個
json的表達式:curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query" : {
"match" : {
"name" : "syske"
}
}
}
'返回結(jié)果:
{
"took" : 50,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.18232156,
"hits" : [
{
"_index" : "megacorp",
"_type" : "employee",
"_id" : "2",
"_score" : 0.18232156,
"_source" : {
"name" : "syske",
"age" : 18,
"about" : "I love to read book",
"interests" : [
"sports",
"music"
]
}
},
{
"_index" : "megacorp",
"_type" : "employee",
"_id" : "1",
"_score" : 0.18232156,
"_source" : {
"name" : "syske",
"age" : 15,
"about" : "I love to read book",
"interests" : [
"sports",
"music"
]
}
}
]
}
}關(guān)于表達式的寫法,我們下面繼續(xù)研究:
curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query" : {
"bool": {
"must": {
"match" : {
"name" : "syske"
}
},
"filter": {
"range" : {
"age" : { "gt" : 15 }
}
}
}
}
}'表達式中的
filter,其實就是對我們前面查出來的結(jié)果進行過濾。關(guān)于表達式的邏輯關(guān)系,我們先補充一點內(nèi)容:上面表達式最終查出的結(jié)果如下:
{
"took" : 18,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.18232156,
"hits" : [
{
"_index" : "megacorp",
"_type" : "employee",
"_id" : "2",
"_score" : 0.18232156,
"_source" : {
"name" : "syske",
"age" : 18,
"about" : "I love to read book",
"interests" : [
"sports",
"music"
]
}
}
]
}
}在我們的
megacorp索引下,名字為syske的employee數(shù)據(jù)有兩條,年齡分別為18和15,因為我們過濾條件為年齡大于15,所以查出的結(jié)果只有年齡為18的。注意:實際在測試的時候,發(fā)現(xiàn)
range表達之只支持gt和lt,其他都不支持。EQ就是EQUAL等于NE就是NOT EQUAL不等于GT就是GREATER THAN大于LT就是LESS THAN小于GE就是GREATER THAN OR EQUAL大于等于LE就是LESS THAN OR EQUAL小于等于
總結(jié)
elasticsearch因為有自己特定的領(lǐng)域特定語言 (DSL),所以我們真正想要用好es,還是要學(xué)好DSL相關(guān)語法的,這也是我截止到目前都沒有通過java去訪問es的一個重要原因。學(xué)東西有時候是不能貪快的,學(xué)好基礎(chǔ)才是關(guān)鍵,只有學(xué)好了基礎(chǔ)內(nèi)容,后面上手才會更容易,畢竟java操作es也是建立在es的各種基礎(chǔ)語法之上的。
