分佈式搜索引擎Elasticsearch的查詢與過濾

1、寫入

先來一個簡單的官方例子,插入的參數爲-XPUT,插入一條記錄。html

curl -XPUT 'http://localhost:9200/test/users/1' -d '{
    "user": "test",
    "post_date": "2009-11-15T14:12:12",
    "message": "Elastic Search"
}'

{
    "_index": "test",
    "_type": "users",
    "_id": "1",
    "_version": 2,
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "created": false
}

從上面的這個例子中,能夠看出ES的http的服務的默認端口9200,後面的/test/users/1是這條記錄的索引部分,體現了它的RESTful風格git

這三級目錄分佈對應了_index,_type,_id 實際上ES上存放的全部的記錄都只能經過三級目錄的方式找到github

  • _id 字段能夠是數字也能夠是字符串。在執行上面的命令時ES會自動建立這些索引json

  • -d 後面跟上了要插入的json格式的記錄api

  • -XPUT 代表這是插入一條數據,ES中叫建立一個索引數組

  • _version 字段,代表了當前記錄的版本號,當你想這個索引從新put一條記錄時,版本號會自動加一bash

2、刪除

刪除的http請求參數爲-XDELETE,經過下面的命令能夠刪除這條記錄:app

curl -XDELETE 'http://localhost:9200/test/users/1?pretty'
{
  "found" : true,
  "_index" : "test",
  "_type" : "users",
  "_id" : "1",
  "_version" : 3,
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  }
}

刪除這條記錄的時候,_verison也會自動加一的。curl

3、查詢

建立了一個索引後,能夠經過下面的方式查詢(參數-XGET)出來elasticsearch

curl -XGET 'http://localhost:9200/test/users/1?pretty'       
{
  "_index" : "test",
  "_type" : "users",
  "_id" : "1",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "user" : "test",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "Elastic Search"
  }
}

執行上面的查詢命令,能夠等到下面的結果,exists表示是否有查詢結果,_source字段是查詢到的記錄。

查詢的時候,能夠將_type設置成爲_all,ES就會返回在_index下全部type中,第一個匹配_id的記錄,還能夠經過參數對返回結果繼續控制,

用fields選取返回的字段,用pretty控制返回的json格式是否更閱讀友好

curl -XGET 'http://localhost:9200/test/users/1?fields=message,user&pretty=true'
{
  "_index" : "test",
  "_type" : "users",
  "_id" : "1",
  "_version" : 3,
  "found" : true,
  "fields" : {
    "message" : [ "Elastic Search" ],
    "user" : [ "test" ]
  }
}

format=yaml能夠設置輸入格式爲YAML

curl -XGET 'http://localhost:9200/test/users/1?fields=message,user&format=yaml' 
---
_index: "test"
_type: "users"
_id: "1"
_version: 1
found: true
fields:
  message:
  - "Elastic Search"
  user:
  - "test"

固然ES還支持一次查詢多組記錄,即multi get,在URI中是使用關鍵字_mget,具體能夠參考ES的文檔multi get

4、更新

ES一樣支持更新,可是更新的方式是經過一個提供的腳本進行的。

ES的作法是,經過index找到相應的存放記錄的節點,而後執行腳本,執行完以後,返回新的索引。實際上執行的是一個get和reindex的過程,在這個過程當中,經過versioning來控制沒有其它的更新操做(這個功能是0.19後可用的)。具體實現的原理應該和elasticsearch Versioning相關。

get,reindex的含義是,ES先取出這條記錄,而後根據新數據生成新記錄,而後在把新記錄放回到ES中(並不會覆蓋老的記錄)。

首先建立一條記錄

curl -XPUT localhost:9200/test/type1/1 -d '{
    "counter" : 1,
    "tags" : ["red"]
}'

將counter的值加4

curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
    "script" : "ctx._source.counter += count",
    "params" : {
        "count" : 4
    }
}'

也能夠添加一個tag的值

curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
    "script" : "ctx._source.tags += tag",
    "params" : {
        "tag" : "blue"
    }
}'

如今還支持upsert功能,即在更新的時候,若是記錄沒有這個key,則插入這個key,下面是一個例子,若是沒有counter字段,則插入該字段:

curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
    "script" : "ctx._source.counter += count",
    "params" : {
        "count" : 4
    },
    "upsert" : {
        "counter" : 1
    }
}'

關於update還有其它不少功能,能夠參考ES的API update

5、搜索

elasticsearch的名字裏面有一個search,那麼主要功能也是search了。

es的search有兩種形式,一是經過URI,二是經過Requst Body。經過URI查詢,即將查詢的語句放入到請求的url中,例如:

curl -XGET 'http://localhost:9200/twitter/tweet/_search?q=user:kimchy'

第二種方式,即在查詢的請求中加入一個doc

curl -XGET 'http://localhost:9200/twitter/tweet/_search' -d '{
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}'

query body的定義能夠查看query DSL 另外兩種查詢方式均可以帶參數,參數的含義參考URI Request和Request Body

ES的搜索功能是能夠跨index和type的,例以下面這幾條命令

curl -XGET 'http://localhost:9200/twitter/_search?q=user:kimchy'
curl -XGET 'http://localhost:9200/twitter/tweet,user/_search?q=user:kimchy'
curl -XGET 'http://localhost:9200/kimchy,elasticsearch/tweet/_search?q=tag:wow'
curl -XGET 'http://localhost:9200/_all/tweet/\_search?q=tag:wow'
curl -XGET 'http://localhost:9200/\_search?q=tag:wow'

第一條是在全部的twitter這個index下的全部type中查找,第二條是在tweet,user這兩個type中查找,第三條是在kimchy,elasticsearch這兩個index的tweet這個type中查找,第四條使用了_all關鍵字,是在全部的index的tweet的type中查找,第五條更暴力,在全部的index和type中查找。

查找還有其它的不少選項,sort高亮,選取返回記錄的域Fields,還能夠對返回的域使用一個腳本進行計算script Fields,或者對返回結果繼續統計Facets,Facets的內容比較多,它支持關鍵詞統計,範圍內統計,直方圖式統計,日期的直方圖式統計,過濾,查詢,還有記錄地理位置距離的統計geo distance。 支持名字過濾Named Filters。 定義搜索類型Search Type 。例如什麼Query And Fetch,Query Then Fetch。 索引加速的功能Index Boost,可讓某一個索引的權重大於另一個。 保持上次檢索的環境告終果Scroll。保留每個命中的score值Explain。 設置命中的min_score。保留版本號Version

Search的參數不少,我也沒有一一看,不過果真是名字裏面有個search,對檢索的各類場景都有支持。

固然還支持多個查詢multi search,例以下面這個例子

cat requests
{"index" : "test"}
{"query" : {"match_all" : {}}, "from" : 0, "size" : 10}
{"index" : "test", "search_type" : "count"}
{"query" : {"match_all" : {}}}
{}
{"query" : {"match_all" : {}}}
 
$ curl -XGET localhost:9200/_msearch --data-binary @requests; echo

6、DSL

一、match

curl -XGET 'localhost:9200/test/_search?pretty' -d'{
    "_source": ["title", "allnum"],
    "query": { 
        "match": { "title": "地鐵跑酷" } 
    }
}'

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 6.692047,
    "hits" : [ {
      "_index" : "test",
      "_type" : "external",
      "_id" : "AVicbl1W9iJMapPz5wea",
      "_score" : 6.692047,
      "_source" : {
        "title" : "地鐵跑酷",
        "allnum" : 104541
      }
    } ]
  }
} 

顯示指定字段,匹配關鍵字

結果格式

  • took – 搜索用的毫秒

  • timed_out – 搜索超時時間

  • _shards – 搜索了多少個片斷 成功搜索多少個 失敗了多少個

  • hits – 搜索的返回結果集

  • hits.total – 結果的總數

  • hits.hits – 實際搜索返回的數組

  • _score and max_score - ignore these fields for now

一旦es搜索返回給你 該連接就斷開了 es並不會想MySQL之類的 一直維護一個鏈接

 

更多限制條件的搜素

curl -XGET 'localhost:9200/test/_search?pretty' -d'{
    "from": 0, 
    "size": 1,
    "_source": ["title", "allnum"],
    "query": { 
        "match": { "title": "地鐵跑酷" }
    },
   "sort": { "allnum": { "order": "desc" }}
}'

二、使用should

curl -XGET 'localhost:9200/test/_search?pretty' -d'{
    "from": 0, 
    "size": 2,
    "_source": ["title", "allnum"],
    "query": { 
        "bool": {
            "should": [
                { "match": { "title": "地鐵跑酷" } },
                { "match": { "title": "星貓跑酷" } }
            ]
        }
    },
   "sort": { "allnum": { "order": "desc" }}
}'

三、使用must/must not

curl -XGET 'localhost:9200/test/_search?pretty' -d'{
    "from": 0, 
    "size": 2,
    "_source": ["title", "allnum"],
    "query": { 
        "bool": {
            "must": [
                { "match": { "title": "地鐵跑酷" } },
                { "match": { "title": "星貓跑酷" } }
            ]
        }
    },
   "sort": { "allnum": { "order": "desc" }}
}'

固然 must /should/must not 能夠聯合起來使用 

四、過濾器

curl -XPOST 'localhost:9200/test/_search?pretty' -d'{
    "query": { 
        "filtered": {
            "query": { 
                 "match_all": {} 
              }, 
             "filter": { 
                 "range": { "allumn": { "gte": 20000, "lte": 30000 } } } } 
               }
}'

五、聚合

curl  -XPOST  'localhost:9200/test/_search?pretty' -d'{
    "size": 0, 
    "aggs": { 
        "group_by_state": { 
            "terms": { "field": "state" } }
         }
}'

六、terms 過濾

curl  -XPOST  'localhost:9200/test/_search?pretty' -d'{ 
  "query": { 
    "terms": { 
      "status": [ 
        304, 
        302 
      ] 
    } 
  } 
}

七、range 過濾

curl  -XPOST  'localhost:9200/test/_search?pretty' -d'{ 
  "query": { 
    "range": { 
      "allnum": { 
        "gt": 1 
      } 
    } 
  } 
}

範圍操做符包含:

  • gt :: 大於

  • gte:: 大於等於

  • lt :: 小於

  • lte:: 小於等於

八、exists 和 missing 過濾

exists 和 missing 過濾能夠用於查找文檔中是否包含指定字段或沒有某個字段,相似於SQL語句中的IS_NULL條件

{ 
    "exists":   { 
        "field":    "title" 
    } 
} 

九、bool 過濾

bool 過濾能夠用來合併多個過濾條件查詢結果的布爾邏輯,它包含一下操做符:

  • must :: 多個查詢條件的徹底匹配,至關於 and。
  • must_not :: 多個查詢條件的相反匹配,至關於 not。
  • should :: 至少有一個查詢條件匹配, 至關於 or。

這些參數能夠分別繼承一個過濾條件或者一個過濾條件的數組:

{ 
    "bool": { 
        "must":     { "term": { "folder": "inbox" }}, 
        "must_not": { "term": { "tag":    "spam"  }}, 
        "should": [ 
                    { "term": { "starred": true   }}, 
                    { "term": { "unread":  true   }} 
        ] 
    } 
}

7、中文分詞

建立索引

curl -XPUT http://localhost:9200/index

建立映射

curl -XPOST http://localhost:9200/index/fulltext/_mapping -d'
{
    "fulltext": {
             "_all": {
            "analyzer": "ik_max_word",
            "search_analyzer": "ik_max_word",
            "term_vector": "no",
            "store": "false"
        },
        "properties": {
            "content": {
                "type": "string",
                "store": "no",
                "term_vector": "with_positions_offsets",
                "analyzer": "ik_max_word",
                "search_analyzer": "ik_max_word",
                "include_in_all": "true",
                "boost": 8
            }
        }
    }
}'

爲索引添加一些內容

curl -XPOST http://localhost:9200/index/fulltext/1 -d'
{"content":"美國留給伊拉克的是個爛攤子嗎"}
'
curl -XPOST http://localhost:9200/index/fulltext/2 -d'
{"content":"公安部:各地校車將享最高路權"}
'
curl -XPOST http://localhost:9200/index/fulltext/3 -d'
{"content":"中韓漁警衝突調查:韓警平均天天扣1艘中國漁船"}
'
curl -XPOST http://localhost:9200/index/fulltext/4 -d'
{"content":"中國駐洛杉磯領事館遭亞裔男子槍擊 嫌犯已自首"}
'

進行查詢

curl -XPOST http://localhost:9200/index/fulltext/_search  -d'
{
    "query" : { "term" : { "content" : "中國" }},
    "highlight" : {
        "pre_tags" : ["<tag1>", "<tag2>"],
        "post_tags" : ["</tag1>", "</tag2>"],
        "fields" : {
            "content" : {}
        }
    }
}
' 

參考

  • http://www.elasticsearch.org

  • https://www.iwwenbo.com/elasticsearch-ik-install/

  • http://samchu.logdown.com/posts/277928-elasticsearch-chinese-word-segmentation

  • https://github.com/medcl/elasticsearch-analysis-ik

相關文章
相關標籤/搜索