全文搜索-ElasticSearch

ElasticSearch

官方文檔html

Elasticsearch是一個開源的搜索引擎,創建在一個全文搜索引擎庫Apache Lucene™基礎之上。 Lucene能夠說是當下最早進,高性能,全功能的搜索引擎庫 - 不管是開源仍是私有。java

可是Lucene僅僅是一個庫。爲了充分發揮其功能,你須要使用Java並將Lucene直接集成到應用程序中。更糟糕的是,您可能須要得到信息檢索學位才能瞭解其工做原理.Lucene 很是複雜。node

Elasticsearch也是使用Java編寫的,它的內部使用Lucene作索引與搜索,可是它的目的是使用全文檢索變得簡單,經過隱藏Lucene的複雜性,取而代之的提供一套簡單一致的RESTful API。git

然而,Elasticsearch不只僅是Lucene,而且也不只僅是一個全文搜索引擎。 它能夠被下面這樣準確的形容:web

  • 一個分佈式的實時文檔存儲,每一個字段能夠被索引與搜索
  • 一個分佈式實時分析搜索引擎
  • 能勝任上百個服務節點的擴展,並支持PB級別的結構化或者非結構化數據

Elasticsearch將全部的功能打包成一個單獨的服務,這樣你能夠經過程序與它提供的簡單的RESTful API進行通訊,可使用本身喜歡的編程語言充當web客戶端,甚至可使用命令行(去充當這個客戶端)。數據庫

就Elasticsearch而言,起步很簡單。對於初學者來講,它預設了一些適當的默認值,並隱藏了複雜的搜索理論知識。它開箱即用。只需最少的理解,你很快就能具備生產力。apache

ElasticSearch交互

java api編程

若是你正在使用 Java,在代碼中你可使用Elasticsearch內置的兩個客戶端:json

節點客戶端(節點客戶端)節點客戶端做爲一個非數據節點加入到本地集羣中。換句話說,它自己不保存任何數據,可是它知道數據在集羣中的哪一個節點中,而且能夠把請求轉發到正確的節點。傳輸客戶端(Transport client)輕量級的傳輸客戶端能夠將請求發送到遠程集羣。它自己不加入集羣,可是它能夠將請求轉發到集羣中的一個節點上。api

兩個Java客戶端都是經過9300端口並使用Elasticsearch原的生傳輸協議狀語從句:集羣交互。集羣中的節點經過端口9300彼此通訊。若是這個端口沒有打開,節點將沒法造成一個集羣。

Java 客戶端做爲節點必須和 Elasticsearch 有相同的 主要 版本;不然,它們之間將沒法互相理解。

使用 Json over http Restfull api

全部其餘語言可使用 RESTful API 經過端口 9200 和 Elasticsearch 進行通訊,你能夠用你最喜好的 web 客戶端訪問 Elasticsearch 。事實上,正如你所看到的,你甚至可使用curl命令來和 Elasticsearch 交互。

Elasticsearch 爲如下語言提供了官方客戶端 --Groovy、JavaScript、.NET、 PHP、 Perl、 Python 和 Ruby--還有不少社區提供的客戶端和插件,全部這些均可以在 Elasticsearch Clients 中找到。

一個 Elasticsearch 請求和任何 HTTP 請求同樣由若干相同的部件組成:

curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
複製代碼

標籤

VERB 適當的 HTTP 方法謂詞 : GETPOSTPUTHEAD 或者 DELETE
PROTOCOL http 或者 https(若是你在 Elasticsearch 前面有一個https 代理)
HOST Elasticsearch 集羣中任意節點的主機名,或者用 localhost 表明本地機器上的節點。
PORT 運行 Elasticsearch HTTP 服務的端口號,默認是 9200 。
PATH API 的終端路徑(例如 _count 將返回集羣中文檔數量)。Path 可能包含多個組件,例如:_cluster/stats 和 _nodes/stats/jvm 。
QUERY_STRING 任意可選的查詢字符串參數 (例如 ?pretty 將格式化地輸出 JSON 返回值,使其更容易閱讀)
BODY 一個 JSON 格式的請求體 (若是請求須要的話)

面向文檔

在應用程序中對象不多隻是一個簡單的鍵和值的列表。一般,它們擁有更復雜的數據結構,可能包括日期、地理信息、其餘對象或者數組等。

也許有一天你想把這些對象存儲在數據庫中。使用關係型數據庫的行和列存儲,這至關因而把一個表現力豐富的對象擠壓到一個很是大的電子表格中:你必須將這個對象扁平化來適應表結構--一般一個字段>對應一列--並且又不得不在每次查詢時從新構造對象。

Elasticsearch 是 面向文檔 的,意味着它存儲整個對象或 文檔_。Elasticsearch 不只存儲文檔,並且 _索引每一個文檔的內容使之能夠被檢索。在 Elasticsearch 中,你 對文檔進行索引、檢索、排序和過濾--而不是對行列數據。這是一種徹底不一樣的思考數據的方式,也是 Elasticsearch 能支持複雜全文檢索的緣由。

json

Elasticsearch 使用 JavaScript Object Notation 或者 JSON 做爲文檔的序列化格式。JSON 序列化被大多數編程語言所支持,而且已經成爲 NoSQL 領域的標準格式。 它簡單、簡潔、易於閱讀。

索引(添加)文檔

put http://ip端口/索引名稱/類型名稱/特定的ID

{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}
複製代碼

檢索文檔

目前咱們已經在Elasticsearch中存儲了一些數據, 接下來就能專一於實現應用的業務需求了。第一個需求是能夠檢索到單個僱員的數據。

這在Elasticsearch中很簡單。簡單地執行 一個HTTP GET請求並指定文檔的地址 - 索引庫,類型和ID。 使用這三個信息能夠返回原始的JSON文檔:

get http://ip端口/索引名稱/類型名稱/特定的ID

{
  "_index" :   "megacorp",
  "_type" :    "employee",
  "_id" :      "1",
  "_version" : 1,
  "found" :    true,
  "_source" :  {
      "first_name" :  "John",
      "last_name" :   "Smith",
      "age" :         25,
      "about" :       "I love to go rock climbing",
      "interests":  [ "sports", "music" ]
  }
}
複製代碼

將HTTP命令由PUT改成GET能夠用來檢索文檔,一樣的,可使用DELETE命令來刪除文檔,以及使用HEAD指令來檢查文檔是否存在。若是想更新已存在的文檔,只需再次PUT。

輕量搜索

_search 用於檢索文檔的全部數據

GET 索引名稱/類型名稱/特定的ID/_search
複製代碼

能夠看到,咱們仍然使用索引庫 以及類型 ,但與指定一個文檔 ID 不一樣,此次使用 `_search 。返回結果包括了全部三個文檔,放在數組 hits 中。一個搜索默認返回十條結果。

{
    "took": 5,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 3,
        "max_score": 1,
        "hits": [
            {
                "_index": "gitboy",
                "_type": "employee",
                "_id": "2",
                "_score": 1,
                "_source": {
                    "first_name": "Jane",
                    "last_name": "Smith",
                    "age": 32,
                    "about": "I like to collect rock albums",
                    "interests": [
                        "music"
                    ]
                }
            }  
        ]
    }
}
複製代碼

經過一個URL參數來傳遞查詢信息給搜索接口過濾篩選條件

GET 索引名稱/類型名稱/_search?q=last_name:Smith
複製代碼

經過查詢表達式使用一個json請求

領域特定語言(DSL), 指定了使用一個JSON請求

GET 索引名稱/類型名稱/_search
{
    "query" : {
        "match" : {
            "last_name" : "Smith"
        }
    }
}
複製代碼

複雜的搜索

使用過濾器filter,its支持高效地執行一個結構化查詢

GET 索引名稱/類型名稱/_search
{
    "query" : {
        "bool": {
            "must": {
                "match" : {
                    "last_name" : "smith" 
                }
            },
            "filter": {
                "range" : {
                    "age" : { "gt" : 30 } 
                }
            }
        }
    }
}
複製代碼

這部分與咱們以前使用的 match 查詢 同樣。

這部分是一個 range 過濾器 , 它能找到年齡大於 30 的文檔,其中 gt 表示_大於(_great than)。

全文搜索

搜索下全部喜歡攀巖(rock climbing)的僱員:

GET 索引名稱/類型名稱/_search
{
    "query" : {
        "match" : {
            "about" : "rock climbing"
        }
    }
}
複製代碼

Elasticsearch 默認按照相關性得分排序,即每一個文檔跟查詢的匹配程度。第一個最高得分的結果很明顯:John Smith 的 about 屬性清楚地寫着 「rock climbing」 。

但爲何 Jane Smith 也做爲結果返回了呢?緣由是她的 about 屬性裏提到了 「rock」 。由於只有 「rock」 而沒有 「climbing」 ,因此她的相關性得分低於 John 的。

這是一個很好的案例,闡明瞭 Elasticsearch 如何 在 全文屬性上搜索並返回相關性最強的結果。Elasticsearch中的 相關性 概念很是重要,也是徹底區別於傳統關係型數據庫的一個概念,數據庫中的一條記錄要麼匹配要麼不匹配。

短語搜索

找出一個屬性中的獨立單詞是沒有問題的,但有時候想要精確匹配一系列單詞或者短語 。 好比, 咱們想執行這樣一個查詢,僅匹配同時包含 「rock」 和 「climbing」 ,而且 兩者以短語 「rock climbing」 的形式緊挨着的僱員記錄。

爲此對 match 查詢稍做調整,使用一個叫作 match_phrase 的查詢:

GET 索引名稱/類型名稱/_search
{
    "query" : {
        "match_phrase" : {
            "about" : "rock climbing"
        }
    }
}
複製代碼

高亮搜索

許多應用都傾向於在每一個搜索結果中 高亮 部分文本片斷,以便讓用戶知道爲什麼該文檔符合查詢條件。在 Elasticsearch 中檢索出高亮片斷也很容易。

GET 索引名稱/類型名稱/_search
{
    "query" : {
        "match_phrase" : {
            "about" : "rock climbing"
        }
    },
    "highlight": {
        "fields" : {
            "about" : {}
        }
    }
}
複製代碼

分析

終於到了最後一個業務需求:支持管理者對僱員目錄作分析。 Elasticsearch有一個功能叫聚合(聚合),容許咱們基於數據生成一些精細的分析結果。聚合與SQL中的GROUP BY相似但更強大。

GET 索引名稱/類型名稱/_search
{
  "query": {
    "match": {
      "last_name": "Smith"
    }
  },
  "aggs": {
    "all_interests": {
      "terms": {
        "field": "interests"
      }
    }
  }
}
複製代碼

相關文章
相關標籤/搜索