用Elasticsearch做檢索
ElasticSearch是一個基於Lucene的搜索服務器。它是一個分佈式,REST風格的搜索和分析引擎。Elasticsearch是用Java開發的。設計用於雲計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。
安裝運行 Elasticsearch
安裝 Elasticsearch 之前,需要先安裝一個較新的版本的 Java。可以從 www.java.com 獲得官方提供的最新版本的 Java。建議使用linux環境
$ echo $JAVA_HOME
/home/users/username/opt/sun-java8/
之後,可以從 elastic 的官網 https://www.elastic.co/downloads/elasticsearch 獲取最新版本的 Elasticsearch。我們使用5.4.0:elasticsearch-5.4.0.tar.gz。解壓即可。
cd elasticsearch-5.4.0
./bin/elasticsearch -d
參數 -d,表示把 Elasticsearch 作為一個守護進程在後臺運行 。
執行命令:curl 'http://localhost:9200/?pretty',返回值如下。表示安裝成功了。
{
"name" : "QR5NuHq",
"cluster_name" : "my-application",
"cluster_uuid" : "FumB0l6rQxa_wb8pb6uW5Q",
"version" : {
"number" : "5.4.0",
"build_hash" : "780f8c4",
"build_date" : "2017-04-28T17:43:27.229Z",
"build_snapshot" : false,
"lucene_version" : "6.5.0"
},
"tagline" : "You Know, for Search"
}
Elasticsearch默認使用9200端口(http.port: 9200)。如果有需要可以在 config/elasticsearch.yml配置文件中修改
索引文檔
我們的項目是對一批小說進行檢索。數據格式如下:
ID | 標題 | 讀者數 | 更新時間戳 | 標籤tag |
1 | 歷史趣談 | 21993888 | 1496682065 | 野史,中國史,歷史 |
2 | 話說漢朝 | 28555776 | 1496683239 | 秦漢,中國史,歷史 |
3 | 大唐風雲錄 | 1018160 | 1496682065 | 隋唐,中國史,歷史 |
4 | 黑白曹操 | 199383 | 1496682350 | 三國,中國史,歷史 |
5 | 品讀資治通鑑 | 318366 | 1496682066 | 先秦,秦漢,中國史,歷史 |
6 | 情愛相對論 | 3514746 | 1496682066 | 大咖,情感 |
7 | 射鵰三部曲 | 163275 | 1496682066 | 講座,中國史,歷史 |
添加文檔索引
curl -XPUT 'localhost:9200/set/article/1?pretty' -H 'Content-Type: application/json' -d'
{
"title" : "歷史趣談",
"tag" : "野史,中國史,歷史",
"count" : 21993888
}'
curl -XPUT 'localhost:9200/set/article/2?pretty' -H 'Content-Type: application/json' -d'
{
"title" : "話說漢朝",
"tag" : "秦漢,中國史,歷史",
"count" : 28555776
}'
路徑 /set/article/1 包含了三部分的信息:
set:索引名稱
article:類型名稱
1:特定文章的ID
查看文檔
curl -XGET 'localhost:9200/set/article/1?pretty'
返回文檔信息
{
"_index" : "set",
"_type" : "article",
"_id" : "1",
"_version" : 1,
"found" : true,
"_source" : {
"title" : "歷史趣談",
"tag" : "野史,中國史,歷史",
"count" : 21993888
}
}
查看所有文檔
curl -XGET 'localhost:9200/set/article/_search?pretty'
刪除文檔
curl -XDELETE 'localhost:9200/set/article/1?pretty'
更新文檔
再次執行添加索引的HTTP命令即可
檢索功能
查詢tag中包含”歷史“標籤的文章
curl -XGET 'localhost:9200/set/article/_search?pretty' -H 'Content-Type: application/json' -d'
{
"query" : {
"match" : {
"tag" : "歷史"
}
}
}'
查詢文章title中包含”歷史“兩個字的文章
curl -XGET 'localhost:9200/set/article/_search?pretty' -H 'Content-Type: application/json' -d'
{
"query" : {
"match" : {
"title" : "歷史"
}
}
}'
查詢tag中包含”歷史“標籤的,並且讀者數大於1218160 的文章
curl -XGET 'localhost:9200/set/article/_search?pretty' -H 'Content-Type: application/json' -d'
{
"query" : {
"bool": {
"must": {
"match" : {
"tag" : "歷史"
}
},
"filter": {
"range" : {
"count" : { "gt" : 1218160 }
}
}
}
}
}'
這部分是一個 range 過濾器,它能找到讀者數大於1218160的文檔,其中 gt 表示_大於(_great than)。
分頁功能
和 SQL 使用 LIMIT 關鍵字返回單個 page 結果類似,Elasticsearch 接受 from 和 size 參數:
size : 顯示應該返回的結果數量,默認是 10
from : 顯示應該跳過的初始結果數量,默認是 0
如果每頁展示 5 條結果,可以用下面方式請求得到 1 到 3 頁的結果:
curl -XGET 'localhost:9200/set/article/_search?pretty&size=5&from=5' -H 'Content-Type: application/json' -d'
{
"query" : {
"match" : {
"tag" : "歷史"
}
}
}'
按屬性排序
按讀者數逆序檢索
curl -XGET 'localhost:9200/set/article/_search?pretty' -H 'Content-Type: application/json' -d'
{
"query" : {
"match" : {
"tag" : "歷史"
}
},
"sort": { "count": { "order": "desc" }}
}'
檢索排序
默認情況下,返回結果是按相關性倒序排列的。
做檢索時,返回字段中有_score值,表示對應文檔的相關性
"hits" : {
"total" : 3,
"max_score" : 0.73636544,
"hits" : [
{
"_index" : "set",
"_type" : "article",
"_id" : "1",
"_score" : 0.73636544,
"_source" : {
"title" : "歷史趣談",
"tag" : "野史,中國史,歷史",
"count" : 21993888
}
},
每個文檔都有相關性評分,用一個正浮點數字段 _score 來表示 。 _score 的評分越高,相關性越高。
查詢語句會為每個文檔生成一個 _score 字段。評分的計算方式主要是計算全文本字段的值相對於全文本檢索詞相似程度。Elasticsearch 的相似度算法 被定義為檢索詞頻率/反向文檔頻率,包括以下內容:
檢索詞頻率
檢索詞在該字段出現的頻率,出現頻率越高,相關性也越高。 字段中出現過 5 次要比只出現過 1 次的相關性高。
反向文檔頻率
每個檢索詞在索引中出現的頻率,頻率越高,相關性越低。檢索詞出現在多數文檔中會比出現在少數文檔中的權重更低。
字段長度
字段的長度是多少,長度越長,相關性越低。 檢索詞出現在一個短的 title 要比同樣的詞出現在一個長的 content 字段權重更大。
當調試一條複雜的查詢語句時,想要理解 _score 究竟是如何計算的,Elasticsearch 在 每個查詢語句中都有一個 explain 參數,將 explain 設為 true 就可以得到更詳細的信息。
curl -XGET 'localhost:9200/set/article/_search?explain&pretty&format=yaml' -H 'Content-Type: application/json' -d'
{
"query" : {
"match" : {
"tag" : "歷史"
}
}
}'