ES 07 - Elasticsearch查詢索引文檔的6種方法


1 Query String Search(查詢串檢索)

這種方法通過HTTP請求的Query String攜帶查詢參數, 因此得名.

適用於臨時性的查詢請求, 比如在終端檢查基礎信息:

# 檢索name中包含Java的文檔, 並按價格降序排序: 
curl -XGET 'http://localhost:9301/book_shop/it_book/_search?q=name:Java&sort=price:desc' 

生產環境中很少使用, 因為請求參數都封裝到Query String中, 難以構建復雜的查詢.

(1) 查詢全部商品:

直接在瀏覽器的URL地址欄內輸入搜索參數:

http://172.16.22.133:9301/book_shop/it_book/_search?q=name:Java

(2) 查詢的結果:

{
    "took": 8,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": 3,
        "max_score": 1,
        "hits": [
            {
                "_index": "book_shop",
                "_type": "it_book",
                "_id": "2",
                "_score": 1,
                "_source": {
                    "name": "深入理解Java虛擬機:JVM高級特性與最佳實踐",
                    "author": "周志明",
                    "category": "編程語言",
                    "desc": "Java圖書領域公認的經典著作",
                    "price": 79,
                    "date": "2013-10-01",
                    "publisher": "機械工業出版社",
                    "tags": [
                        "Java",
                        "虛擬機",
                        "最佳實踐"
                    ]
                }
            },
            // 省略另外兩條記錄
        ]
    }
}

(3) 查詢結果中的各個參數的含義:

took: 此次檢索耗費的時間, 單位是毫秒;

timed_out: 是否超出規定的檢索時間, 這里沒有設置, 后續會講解此參數;

_shards: 被查詢的index被分散成多個分片, 所以搜索請求會分發到所有的primary shard(或primary shard對應的某個replica shard)上, 這里顯示各個分片是否查詢成功的信息;

hits: 命中的文檔情況, 有如下參數:

total: 符合條件的文檔總數, 即hit(命中)數;
max_score: Lucene底層對檢索到的文檔的相關度的評分, 相關度越高, 說明越匹配, score的值也就越高.
hits: 命中的所有document的詳細數據.

2 Query DSL(ES特定語法檢索)

DSL: Domain Specified Language, 特定領域的語言, 一般需要Kibana等工具配合操作.

這種方式把查詢參數構建成JSON格式的數據, 並封裝到HTTP請求的Request Body(請求體)中, 可以構建各類復雜的查詢語法, 功能要比Query String Search強大很多.

(1) 查詢全部商品:

GET book_shop/it_book/_search
{
    "query": { "match_all": {} }
}

(2) 查詢name中包含Java的商品, 並按price降序排序:

GET book_shop/it_book/_search
{
    "query": {
        "match": {
            "name": "Java"
        }
    },
    "sort": [
        { "price": "desc" }
    ]
}

(3) 分頁查詢商品 - 每頁顯示1條, 顯示第3頁:

GET book_shop/it_book/_search
{
    "query": { "match_all": {} },
    "from": 2,
    "size": 1
}

(4) 只查詢商品的名稱和價格:

GET book_shop/it_book/_search
{
    "query": {"match_all": {}},
    "_source": ["name", "price"]
}

—— 上述各類語法可以組合使用, 具體使用方法后續會陸續介紹.

3 Query Filter(過濾檢索)

過濾查詢, 比如: 查詢name中包含Java, 且price不大於80元的商品:

GET book_shop/it_book/_search
{
    "query": {
        "bool": {
          	"must": {
                "match": {"name": "Java"}	// name中含有Java
            },
            "filter": {
                "range": { 
                    "price": {"lte": 80.0}	// 價格不大於80.0
                }
            }
        }
    }
}

4 Full Text Search(全文檢索)

(1) 查詢描述信息desc中包含"Java圖書"的文檔, 只顯示name和desc的值:

GET book_shop/it_book/_search
{
    "query": {
        "match": {"desc": "Java圖書"}
    },
    "_source": ["name", "desc"]
}

(2) 查詢結果中有2條數據符合要求:

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 0.8630463,
    "hits" : [
      {
        "_index" : "book_shop",
        "_type" : "it_book",
        "_id" : "2",
        "_score" : 0.8630463,
        "_source" : {
          "name" : "深入理解Java虛擬機:JVM高級特性與最佳實踐",
          "desc" : "Java圖書領域公認的經典著作"			// desc中有"Java"和"圖書"
        }
      },
      {
        "_index" : "book_shop",
        "_type" : "it_book",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "name" : "Java編程思想(第4版)",
          "desc" : "Java學習必讀經典,殿堂級著作!"		// desc中有"Java"
        }
      }
    ]
  }
}

(3) 全文檢索的過程 —— 對查詢結果的說明:

Elasticsearch會對字段"desc"的內容進行分詞, 並建立倒排索引.

也就是說, 這里會把 "Java圖書" 分詞為 "Java"、"圖"、"書" 3個, 檢索時將匹配desc中含有 "Java"、"圖"、"書" 中任意一個分詞的文檔.

—— 對於中文分詞, 可以通過IK分詞器, 把"Java圖書"分解為"Java"、"圖書" 2個詞, 參考博主的文章:ES XX - Elasticsearch中使用IK中文分詞器.

5 Phrase Search(短語檢索)

Full Text Search會對檢索文本作分詞處理, 然后從倒排索引中作匹配查詢, 如果一個文檔的對應field中存在任意一個分解后的詞, 那么這個文檔就算匹配檢索條件.

Phrase Search不會對檢索串進行分詞處理, 只有一個文檔的對應field中包含與檢索文本完全一致的內容, 該文檔才算匹配檢索條件, 也才能作為結果返回 —— 可以理解為全文檢索場景下的部分精確匹配.

(1) 精確查詢desc中包含"Java圖書"的文檔:

GET book_shop/it_book/_search
{
    "query": {
        "match_phrase": {
            "desc": "Java圖書"
        }
    },
    "_source": ["name", "desc"]
}

(2) 查詢結果只有一條數據符合要求了:

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.8630463,
    "hits" : [
      {
        "_index" : "book_shop",
        "_type" : "it_book",
        "_id" : "2",
        "_score" : 0.8630463,
        "_source" : {
          "name" : "深入理解Java虛擬機:JVM高級特性與最佳實踐",
          "desc" : "Java圖書領域公認的經典著作"		// desc中精確含有"Java圖書"
        }
      }
    ]
  }
}

6 Highlight Search(高亮檢索)

(1) 分頁查詢desc中包含"Java圖書"的文檔, 頁大小為1, 顯示第1頁, 並對搜索條件高亮處理:

GET book_shop/it_book/_search
{
    "query": {
        "match": {"desc": "Java圖書"}
    },
    "from": 0,
    "size": 1,
    "highlight": {
        "fields": {"desc": {}}
    },
    "_source": ["name", "desc"]
}

(2) 查詢結果:

{
  "took" : 6,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 0.8630463,
    "hits" : [
      {
        "_index" : "book_shop1",
        "_type" : "it_book",
        "_id" : "2",
        "_score" : 0.8630463,
        "_source" : {
          "name" : "深入理解Java虛擬機:JVM高級特性與最佳實踐",
          "desc" : "Java圖書領域公認的經典著作"
        },
        "highlight" : {		// 高亮顯示, 默認添加<em>標簽
          "desc" : [
            "<em>Java</em><em>圖</em><em>書</em>領域公認的經典著作"
          ]
        }
      }
    ]
  }
}

從上述結果的"<em>Java</em><em>圖</em><em>書</em>也可以看出, ES底層對desc字段的值"Java圖書"進行了分詞處理:

說明: 本文的六種查詢方法, 只是一個簡單的入門, 詳細使用方法會在后續的學習中逐一演示.

版權聲明

作者: 馬瘦風(https://healchow.com)

出處: 博客園 馬瘦風的博客(https://www.cnblogs.com/shoufeng)

感謝閱讀, 如果文章有幫助或啟發到你, 點個[好文要頂👆] 或 [推薦👍] 吧😜

本文版權歸博主所有, 歡迎轉載, 但 [必須在文章頁面明顯位置標明原文鏈接], 否則博主保留追究相關人員法律責任的權利.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM