ElasticSearch搜索介紹四

ElasticSearch搜索html

 

最基礎的搜索:java

curl -XGET http://localhost:9200/_search

返回的結果爲:數據庫

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 16,
    "successful": 16,
    "failed": 0
  },
  "hits": {
    "total": 13,
    "max_score": 1,
    "hits": [
      {
        "_index": ".kibana",
        "_type": "config",
        "_id": "5.5.1",
        "_score": 1,
        "_source": {
          "buildNum": 15405
        }
      },
      {
        "_index": "people",
        "_type": "man",
        "_id": "8",
        "_score": 1,
        "_source": {
          "name": "deda",
          "age": 31,
          "job": "stu"
        }
      },
      {
        "_index": "people",
        "_type": "man",
        "_id": "30",
        "_score": 1,
        "_source": {
          "name": "tomi",
          "age": 19,
          "job": "master"
        }
      },
      {
        "_index": "people",
        "_type": "man",
        "_id": "5",
        "_score": 1,
        "_source": {
          "name": "ming",
          "age": 33,
          "job": "coding",
          "like": "football",
          "tel": "122334"
        }
      },
      {
        "_index": "people",
        "_type": "man",
        "_id": "2",
        "_score": 1,
        "_source": {
          "name": "fukk",
          "age": 30,
          "job": "stu"
        }
      },
      {
        "_index": "people",
        "_type": "man",
        "_id": "4",
        "_score": 1,
        "_source": {
          "name": "mask",
          "age": 40,
          "job": "CEO"
        }
      },
      {
        "_index": "people",
        "_type": "man",
        "_id": "6",
        "_score": 1,
        "_source": {
          "name": "nan",
          "age": 25,
          "job": "coding"
        }
      },
      {
        "_index": "peoples",
        "_type": "employee",
        "_id": "2",
        "_score": 1,
        "_source": {
          "first_name": "Jane",
          "last_name": "Smith",
          "age": 32,
          "about": "I like to collect rock albums",
          "interests": [
            "music"
          ]
        }
      },
      {
        "_index": "megacorp",
        "_type": "employee",
        "_id": "1",
        "_score": 1,
        "_source": {
          "first_name": "John",
          "last_name": "Smith",
          "age": 25,
          "about": "I love to go rock climbing",
          "interests": [
            "sports",
            "music"
          ]
        }
      },
      {
        "_index": "people",
        "_type": "man",
        "_id": "1",
        "_score": 1,
        "_source": {
          "name": "ahaii",
          "age": 27,
          "job": "coding"
        }
      }
    ]
  }
}
View Code

索引全部文檔,返回結果中默認顯示前十條數據。數組

hits:緩存

返回結果中最重要的部分是 hits ,它 包含 total 字段來表示匹配到的文檔總數,而且一個 hits 數組包含所查詢結果的前十個文檔。app

在 hits 數組中每一個結果包含文檔的 _index 、 _type 、 _id ,加上 _source 字段。這意味着咱們能夠直接從返回的搜索結果中使用整個文檔。這不像其餘的搜索引擎,僅僅返回文檔的ID,須要你單獨去獲取文檔。curl

每一個結果還有一個 _score ,它衡量了文檔與查詢的匹配程度。默認狀況下,首先返回最相關的文檔結果,就是說,返回的文檔是按照 _score 降序排列的。在這個例子中,咱們沒有指定任何查詢,故全部的文檔具備相同的相關性,所以對全部的結果而言 1 是中性的 _score 。elasticsearch

took:ide

took 值表示執行整個搜索請求耗費了多少毫秒。測試

shards:

_shards 部分告訴咱們在查詢中參與分片的總數,以及這些分片成功了多少個失敗了多少個。正常狀況下咱們不但願分片失敗,可是分片失敗是可能發生的。若是咱們遭遇到一種災難級別的故障,在這個故障中丟失了相同分片的原始數據和副本,那麼對這個分片將沒有可用副原本對搜索請求做出響應。倘若這樣,Elasticsearch 將報告這個分片是失敗的,可是會繼續返回剩餘分片的結果。

不一樣索引、不一樣類型的搜索:

/_search在全部的索引中搜索全部的類型

/gb/_search在 gb 索引中搜索全部的類型

/gb,us/_search在 gb 和 us 索引中搜索全部的文檔

/g*,u*/_search在任何以 g 或者 u 開頭的索引中搜索全部的類型

/gb/user/_search在 gb 索引中搜索 user 類型

/gb,us/user,tweet/_search在 gb 和 us 索引中搜索 user 和 tweet 類型

/_all/user,tweet/_search在全部的索引中搜索 user 和 tweet 類型

當在單一的索引下進行搜索的時候,Elasticsearch 轉發請求到索引的每一個分片中,能夠是主分片也能夠是副本分片,而後從每一個分片中收集結果。多索引搜索剛好也是用相同的方式工做的--只是會涉及到更多的分片。

搜索一個索引有五個主分片和搜索五個索引各有一個分片準確來所說是等價的。

 

搜索結果分頁:

和 SQL 使用 LIMIT 關鍵字返回單個 page 結果的方法相同,Elasticsearch 接受 from 和 size 參數:

size
顯示應該返回的結果數量,默認是  10
from
顯示應該跳過的初始結果數量,默認是  0

 顯示3條搜索結果:

curl -XGET http://localhost:9200/_search?size=3

顯示第4-6條搜索結果:

curl -XGET http://localhost:9200/_search?size=3&from=3

顯示第7-9條搜索結果:

curl -XGET http://localhost:9200/_search?size=3&from=6

 

ElasticSearh搜索API的形式:

一、在查詢字符串中傳遞參數

查詢man類型(表)中全部name字段爲ahaii的文檔:

curl -XGET http://localhost:9200/_all/man/_search?q=name:ahaii

搜索結果以下:

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 16,
    "successful": 16,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.6931472,
    "hits": [
      {
        "_index": "people",
        "_type": "man",
        "_id": "1",
        "_score": 0.6931472,
        "_source": {
          "name": "ahaii",
          "age": 27,
          "job": "coding"
        }
      }
    ]
  }
}

 

二、使用請求體查詢

使用請求體查詢時,如ElasticSearch系列第一片中介紹。

 

若是查詢多個不一樣的字段,Elasticsearch 取出全部字段的值拼接成一個大的字符串,做爲 _all 字段進行索引。

例如,在索引一個包含以下字段的文檔時:

{
    "name":    "tim",
    "job":     "CEO",
    "age":     "25"
}

這就好似增長了一個名叫 _all 的額外字段,來檢索下面這個字符串:

tim CEO 25

除非設置特定字段,不然查詢字符串就使用 _all 字段進行搜索。

 

ElasticSearch中將數據分爲兩類,精確值(詞條 term)全文

精確值很容易查詢。結果是二進制的:要麼匹配查詢,要麼不匹配。這種數據的查詢方式很想關係型數據庫中的SQL語句。

精確值查詢須要徹底匹配,即字符的大小寫,字符的數量和位置都是相同的,詞條(term)查詢使用字符的徹底匹配方式進行文本搜索,詞條查詢不會分析(analyze)查詢字符串,給定的字段必須徹底匹配詞條查詢中指定的字符串。因爲詞條查詢的字符串是未經分析(analyzed)的詞條,所以,詞條查詢常常用於結構化的數據,例如,數值,日期等,

全文查詢數據要微妙的多。咱們問的不僅是「這個文檔匹配查詢嗎」,而是「該文檔匹配查詢的程度有多大?」換句話說,該文檔與給定查詢的相關性如何?

爲了促進這類在全文域中的查詢,Elasticsearch 首先分析文檔,以後根據結果建立倒排索引 。

倒排索引:

閱讀這片博文:http://blog.csdn.net/hguisu/article/details/7962350

爲了獲取到等多的相關文檔,在分詞的時候,還須要對單詞作一些其餘操做。若是咱們將詞條規範爲標準模式,那麼咱們能夠找到與用戶搜索的詞條不徹底一致,但具備足夠相關性的文檔,好比:

一、忽略關鍵詞的大小寫

二、忽略關鍵詞的單複數形式

三、模糊匹配詞意相同或相近

 

單詞分析與過濾

ElasticSearch中,分詞和標準化的過程就是分析的過程。

分析包含如下兩個過程:

一、將一塊文本分紅適合於倒排索引的獨立的詞條

二、將這些詞條統一化爲標準格式以提升它們的「可搜索性」

以上工做由分析器完成。分析器其實是由三個功能組成:

一、字符串過濾器:

首先,字符串按順序經過每一個 字符過濾器 。他們的任務是在分詞前整理字符串。一個字符過濾器能夠用來去掉HTML,或者將 & 轉化成 `and`。

二、分詞器:

其次,字符串被 分詞器 分爲單個的詞條。一個簡單的分詞器遇到空格和標點的時候,可能會將文本拆分紅詞條。

三、Token過濾器:

最後,詞條按順序經過每一個 token 過濾器 。這個過程可能會改變詞條(例如,小寫化 Quick ),刪除詞條(例如, 像 a`, `and`, `the 等無用詞),或者增長詞條(例如,像 jump 和 leap 這種同義詞)。

 

ElasticSearch內置分析器種類:

每種分析器對字符串的處理方式不一樣,以語句"Set the shape to semi-transparent by calling set_trans(5)"爲例:

一、標準分詞器:

標準分析器是Elasticsearch默認使用的分析器。它是分析各類語言文本最經常使用的選擇。它根據 Unicode 聯盟 定義的 單詞邊界 劃分文本。刪除絕大部分標點。最後,將詞條小寫。它會產生:

set, the, shape, to, semi, transparent, by, calling, set_trans, 5

二、簡單分析器:

簡單分析器在任何不是字母的地方分隔文本,將詞條小寫。它會產生:

set, the, shape, to, semi, transparent, by, calling, set, trans

三、空格分析器:

空格分析器在空格的地方劃分文本。它會產生:

Set, the, shape, to, semi-transparent, by, calling, set_trans(5)

四、語言分析器:

特定語言分析器可用於不少語言。它們能夠考慮指定語言的特色。例如, 英語 分析器附帶了一組英語無用詞(經常使用單詞,例如 and 或者 the ,它們對相關性沒有多少影響),它們會被刪除。 因爲理解英語語法的規則,這個分詞器能夠提取英語單詞的詞幹 。

英語分詞器會產生下面的詞條:

set, shape, semi, transpar, call, set_tran, 5

注意,transparent、 calling 和 set_trans 已經變爲詞根格式。

當全文查詢時,es會對查詢字符串作一樣的分析處理,以保證搜索的詞條格式與索引中的詞條格式保持一致。

當精確查詢時,es不會分析查詢字符串,而是查詢匹配到的精確值。

 

測試分析器:

爲了理解es內部是分詞的過程,可使用 analyze API 測試分析器來看文本是如何被分析的。在消息體裏,指定分析器和要分析的文本:

curl -XGET http://localhost:9200/_analyze
{
  "analyzer": "standard",
  "text": "hello this is my blog."
}

能夠獲得如下結果:

{
  "tokens": [
    {
      "token": "hello",
      "start_offset": 0,
      "end_offset": 5,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "this",
      "start_offset": 6,
      "end_offset": 10,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "is",
      "start_offset": 11,
      "end_offset": 13,
      "type": "<ALPHANUM>",
      "position": 2
    },
    {
      "token": "my",
      "start_offset": 14,
      "end_offset": 16,
      "type": "<ALPHANUM>",
      "position": 3
    },
    {
      "token": "blog",
      "start_offset": 17,
      "end_offset": 21,
      "type": "<ALPHANUM>",
      "position": 4
    }
  ]
}
View Code

結果中,token是實際存儲到索引中的詞條,position 指明詞條在原始文本中出現的位置。 start_offset 和 end_offset 指明字符在原始字符串中的位置。

 

映射

爲了可以將時間域視爲時間,數字域視爲數字,字符串域視爲全文或精確值字符串, Elasticsearch 須要知道每一個域中數據的類型。這個信息包含在映射中。

ElasticSearch中核心域類型:

一、字符串:string

二、整型:byte,short,long,integer

三、浮點:float,double

四、布爾:boolean

五、日期:date

 

自定義映射:

域裏最重要的屬性是type,對於不是string的域,通常只須要設置type:

{
    "age": {
        "type": "integer"
    }
}

默認, string 類型域會被認爲包含全文。就是說,它們的值在索引前,會經過 一個分析器,針對於這個域的查詢在搜索前也會通過一個分析器。

string 域映射的兩個最重要 屬性是 index 和 analyzer 。

index:

index 屬性控制怎樣索引字符串。它能夠是下面三個值:

一、analyzed:

首先分析字符串,而後索引它。換句話說,以全文索引這個域。

二、not_analyzed:

索引這個域,因此它可以被搜索,但索引的是精確值。不會對它進行分析。

三、no:

不索引這個域。這個域不會被搜索到。

 

string 域 index 屬性默認是 analyzed 。若是咱們想映射這個字段爲一個精確值(不分析,精確匹配),咱們須要設置它爲 not_analyzed:

{
    "tag": {
        "type":     "string",
        "index":    "not_analyzed"
    }
}

注意,只有string域能夠被分析,像其餘如long、double、date類型,永遠不會被分析。

 

analyzer:

對於 analyzed 字符串域,用 analyzer 屬性指定在搜索和索引時使用的分析器。默認, Elasticsearch 使用 standard 分析器, 但能夠指定一個內置的分析器替代它,例如 whitespace 、 simple 和 english:

{
    "man": {
        "type": "string",
        "analyzer": "english"
    }
}

可是,能夠更新一個映射來添加一個新域,但不能將一個存在的域從 analyzed 改成 not_analyzed 。

 

空域:

下面三種域被認爲是空的,它們將不會被索引:

"null_value":               null,
"empty_array":              [],
"array_with_null_value":    [ null ]

 

評分查詢與過濾查詢:

評分查詢:

判斷這個文檔是否匹配,同時它還須要判斷這個文檔匹配的有多好(相關性得分)。 此查詢的典型用法是用於查找如下文檔:

一、查找與 full text search 這個詞語最佳匹配的文檔
二、包含 run 這個詞,也能匹配 runs 、 running 、 jog 或者 sprint
三、包含 quick 、 brown 和 fox 這幾個詞 — 詞之間離的越近,文檔相關性越高
四、標有 lucene 、 search 或者 java 標籤 — 標籤越多,相關性越高

評分查詢(scoring queries)不只僅要找出 匹配的文檔,還要計算每一個匹配文檔的相關性,計算相關性使得它們比不評分查詢費力的多。同時,查詢結果並不緩存。

過濾查詢:

過濾查詢是一個「不評分」或者「過濾」查詢。即,這個查詢只是簡單的問一個問題:「這篇文檔是否匹配?」。回答也是很是的簡單,yes 或者 no ,兩者必居其一。

一、created 時間是否在 2013 與 2014 這個區間?
2、status 字段是否包含 published 這個單詞?
三、lat_lon 字段表示的位置是否在指定點的 10km 範圍內?

過濾查詢(Filtering queries)只是簡單的檢查包含或者排除,這就使得計算起來很是快。考慮到至少有一個過濾查詢(filtering query)的結果是 「稀少的」(不多匹配的文檔),而且常用不評分查詢(non-scoring queries),結果會被緩存到內存中以便快速讀取,因此有各類各樣的手段來優化查詢結果

相關文章
相關標籤/搜索