1. 程式人生 > >Elasticsearch筆記-深入查詢

Elasticsearch筆記-深入查詢

上一篇筆記Elasticsearch筆記-索引與查詢我們介紹了ES的簡單的增刪查改,這一次我們深入ES較為複雜的查詢,比如SQL中常用的select in 、模糊查詢、返回部分欄位等等。

一般來說,ES的真正用途在於分散式的搜尋引擎,由於其穩定快速的查詢效能又被當做資料庫使用。

承接上一篇資料,此時posts索引article型別中的資料如下:

{
    "hits": {
        "total": 4,
        "max_score": 1,
        "hits": [{
            "_index": "posts",
            "_type
": "article", "_id": "5", "_score": 1, "_source": { "id": 5, "name": "生活日誌", "author": "wthfeng", "date": "2015-09-21", "contents": "這是日常生活的記錄" } }, { "_index
": "posts", "_type": "article", "_id": "4", "_score": 1, "_source": { "id": 4, "name": "javascript指南", "author": "wthfeng", "date": "2016-09-21", "contents": "js的權威指南"
}
}, { "_index": "posts", "_type": "article", "_id": "2", "_score": 1, "_source": { "id": 2, "name": "更新後的文件", "author": "wthfeng", "date": "2016-10-23", "contents": "這是我的javascript學習筆記", "brief": "簡介,這是新加的欄位" } }, { "_index": "posts", "_type": "article", "_id": "1", "_score": 1, "_source": { "id": 1, "name": "ES更新過的文件", "author": "wthfeng", "date": "2016-10-25", "contents": "這是更新內容" } }]
}
}

1. 返回指定欄位(fields)

檢視我們的返回結果,每一個都帶有_source欄位,裡面包含原始的資料。我們都是從這個欄位查詢出所需的結果。返回_source 欄位是預設的行為,如果我們只想返回某些欄位,那這些欄位在建立索引時必須開啟store欄位。

上一篇定義的article對映部分:

{
    "properties": {
        "id": {
            "type": "long",
            "store": "yes"  //開啟儲存
        },
        //......省略其他欄位
        "contents": {
            "type": "string",
            "store": "no"  //未開啟儲存,預設
        }
    }
}

現在要求返回文章名稱帶文件 兩詞的所有文章,且只返回idname欄位。

curl localhost:9200/posts/article/_search?pretty -d @search.json

{
    "fields": ["id", "name"],
    "query": {
        "match": {
            "name": "文件"
        }
    }
}

返回資料部分

  {
    "hits": {
        "total": 2,
        "max_score": 0.53033006,
        "hits": [{
            "_index": "posts",
            "_type": "article",
            "_id": "2",
            "_score": 0.53033006,
            "fields": {
                "name": ["更新後的文件"],
                "id": [2]
            }
        }, {
            "_index": "posts",
            "_type": "article",
            "_id": "1",
            "_score": 0.16273327,
            "fields": {
                "name": ["ES更新過的文件"],
                "id": [1]
            }
        }]
    }
  }

可見結果只有指定的欄位。且用fields欄位代替了_source欄位。類似SQL中:

select id,name from article where name like '%文件%'
  • 如果查詢中沒有fields欄位,那預設返回_source欄位
  • 雖然返回更少欄位,但返回_source欄位比返回多個儲存欄位效能要好,所以無特殊要求,返回_source較好。

2. 多詞條查詢(terms)

多詞條查詢類似於SQL中的in 操作符。可以匹配在查詢內容中含有的多個詞條。注意,terms匹配的是未經分析的詞條,也就是必須完全匹配。

查詢16年10月23號和25號發表的文章

curl localhost:9200/posts/article/_search -d @search.json

{
    "query":{
        "terms":{
            "date":["2016-10-23","2016-10-25"]
        }
    }
}

注意:terms查詢的詞是未經分析的。它相當於term的複數版本。
類似於SQL:

select * from article where date in('2016-10-23','2016-10-25') 

3. 範圍查詢(range)

範圍查詢(range)即返回指定範圍的文件,多用於數值型和日期型中。

查詢日期在10月23日及之前發表的,且文章名含有“指南”兩字文章。

curl localhost:9200/posts/article/_search?pretty -d @search.json

{
    "query":{
        "range":{
            "date":{
                "lte":"2016-10-23"
            }
        }
    }
}

結果正確返回,這裡就不貼了。範圍查詢支援以下引數:

  • gte :大於或等於
  • gt :大於
  • lte :小於或等於
  • lt :小於

此例在SQL中很容易表示:

select * from article where date <= '2016-10-23'

4. 排序(sort)

預設的ES按文件的相關度排序,即與指定查詢吻合度最高的排在前面。如果我們想修改預設排序,需使用sort 欄位與query 欄位並列。

查詢文件內容含有”的”字所有文件並按日期、id排序

curl localhost:9200/posts/article/_search?pretty -d @search.json

{
    "query":{
        "match":{
            "contents":"的"
        }
    },
    "sort":[
        {"date":"desc"},
        {"id":"asc"}
    ]
}

sort接收一個數組,可以指定多個排序欄位,用ascdesc 指定正序倒序

SQL 語句為

select * from article where contents like '%的%' order by date desc,id asc

預設欄位的排序

預設情況下,如果某文件沒有指定的排序欄位或該值為null,那麼,如果升序排,該文件排在最前面,倒序排排在最後面。也就是預設值的文件序列號是最小的。
我們可以用missing 修改這種預設行為。_first 指定排在最前列,_last 指定排在最後列。還可指定具體數值,則預設值就當做此值。

將預設值都放在前列

{
    "query":{
        "match":{
            "contents":"的"
        }
    },
    "sort":[
        {"date":{
            "order":"desc",
            "missing":"_first"

        }},
        {"id":{
            "order":"asc",
            "missing":"_first"
        }}
    ]
}

布林查詢(bool)

是時候將這些查詢聚在一起了,布林查詢負責此工作。類似於SQL中andor 等的作用
在布林查詢中

  • should : 類似於or,可以匹配條件也可以不匹配
  • must : 類似於and,必須匹配
  • must_not : 類似於!=,必須不匹配

以上關鍵字需包含在bool 語句中。

查詢16年10月以來名稱含有“ES”的文件,且id不為1

{
    "query": {
        "bool": {
            "should": {

            },
            "must": [{
                "match": {
                    "name": {
                        "query": "ES"
                    }
                }
            }, {
                "range": {
                    "date": {
                        "gte": "2016-10-01"
                    }
                }
            }],
            "must_not": {
                "term": {
                    "id": "1"
                }
            }
        }
    }
}

需要注意的是查詢的格式要求,should、must、must_not可以帶一個或多個查詢條件。注意無論怎樣的查詢條件都首先滿足json的格式要求。

上面寫成SQL類似於

select * from article where name like '%ES%' and date > '2016-10-01' and id !=1 

———————end ———————–