[勾勒一個自己的搜索引擎]ES2輕量級搜索

概述

ES是一個搜索引擎,我們之所以要使用它就是為了借助它快速構(gòu)建全文索引,幫助我們快速檢索數(shù)據(jù)。

本文接著上篇文章ElasticSearch1初步使用繼續(xù)來通過blogs索引實例說明如何簡單的借助ES實現(xiàn)輕量級搜索功能。

問題

本文主要以應(yīng)用ES為基本問題,主要探索ES通過GET方法進(jìn)行搜索的使用方法。在實驗的示例中本文也會簡要的描述ES相關(guān)的理論知識。

如何使用索引進(jìn)行搜索,對搜索結(jié)果進(jìn)行分頁,并使用簡單的條件來過濾搜過結(jié)果是本文需要探討的問題。

方法

本文采用對照RDBMS中SELECT功能的方法來描述ES中的輕量級搜索的概念,從總體上來講,在ES中搜索數(shù)據(jù)其實和在RDBMS中SELECT數(shù)據(jù)是一樣的,都可以指定搜索(查詢)條件,都可以設(shè)置返回字段,也都可以進(jìn)行一定的聚合運(yùn)算。只不過ES搜索引擎使用全文搜索得到的結(jié)果會根據(jù)內(nèi)容與搜索關(guān)鍵字的匹配程度給與每個結(jié)果一個權(quán)重,這個權(quán)重就作為搜索結(jié)果排序的依據(jù)。而RDBMS完全是依照ORDER BY子句中指定的排序規(guī)則進(jìn)行排序的。

說明:

ES REST API所提供的完全在URL中描述參數(shù)的接口就是輕量級搜索接口,換句話說輕量級搜索接口都是使用GET方法的。所以文中示例使用的地址和API語法總結(jié)如沒有對HTTP請求方法做出特殊聲明,均使用GET方法。

對本文中語法說明特殊字符的聲明:

  • {a} 代表a變量,如{host}代表主機(jī)名或ip地址,{index}代表索引名
  • [] 代表可出現(xiàn)也可不出現(xiàn),一般情況下帶有[]標(biāo)識的變量出現(xiàn)和不出現(xiàn)會有不同的含義。對于URL開頭的[http[s]://]表達(dá)式,如果省略整個表達(dá)式則系統(tǒng)會默認(rèn)使用http協(xié)議。
  • ... 對返回結(jié)果或請求內(nèi)容進(jìn)行部分省略。

全量數(shù)據(jù)搜索

語法

請求信息:

[http[s]://]{host}:{port}/[{index}/[{type}/]]_search

響應(yīng)信息:

{
    "took": 7,//執(zhí)行搜索請求的耗時,單位毫秒
    "timed_out": false,//搜索是否超時
    "_shards":{//參與本次搜索的分片信息
        "total": 5,//參與本次搜索的分票總個數(shù)
        "successful": 5,//有多少個分片成功的完成了搜索任務(wù)
        "failed": 0 //有多少分片執(zhí)行搜索任務(wù)失敗
    },
    "hits":{ //搜過結(jié)果信息
        "total": 1,//匹配到的文檔總數(shù)
        "max_score": 1.0193838,//查詢所匹配文檔的 _score 的最大值。
        "hits":[...]//匹配到的文檔詳細(xì)信息結(jié)果集
    }
}

在沒有指定分頁條件的情況下,響應(yīng)信息默認(rèn)返回10條結(jié)果。

示例

搜索blogs索引下,articles類型下的全部文檔。這是一個沒有任何過濾條件的最簡單的搜索。

請求信息:

http://ubuntu:9200/blogs/articles/_search

響應(yīng)信息:

{
  ...,
    "hits" : [
      {
        "_index" : "blogs",
        "_type" : "articles",
        "_id" : "AV6GlxJvP5Roqj_P-AOw",
        "_score" : 1.0,
        "_source" : {
          "title" : "ES自動生成id索引",
          "author" : "為為",
          "since" : "2017-09-16 20:20:20",
          "categorie" : "搜索引擎",
          "tags" : [
            "java",
            "研發(fā)"
          ],
          "body" : "如果你無法手動對文檔進(jìn)行編號,可以使用POST方法向ES中索引一個新文檔,其操作方法和鏈接規(guī)則如圖8所示。"
        }
      },
      ...//更多內(nèi)容暫時省略
    ]
  }
}

簡單條件篩選

簡單的條件篩選就像是給SQL中的SELECT語句加上WHERE子句,從而限定只查找滿足某些條件的結(jié)果。

語法

在請求路徑中使用q參數(shù),并將查詢條件賦值給q

[http[s]://]{host}:{port}/[{index}/[{type}/]]_search?q={param_name}:{param_value}
示例

我們搜索一下文章的tags包含 標(biāo)簽1 的文章。

請求參數(shù):

http://ubuntu:9200/blogs/articles/_search?q=tags:標(biāo)簽1

響應(yīng)參數(shù):

{
  ...,
  "hits" : {
    ...
    "hits" : [
      {
        "_index" : "blogs",
        "_type" : "articles",
        "_id" : "1",
        "_score" : 1.0193838,
        "_source" : {
          "title" : "第一篇文章",
          "author" : "馬華",
          "since" : "2017-09-10 20:20:20",
          "categorie" : "科學(xué)讀物",
          "tags" : [
            "標(biāo)簽1",
            "標(biāo)簽2"
          ],
          "body" : "測試文章內(nèi)容"
        }
      }
    ]
  }
}

分頁

我們在SQL中SELECT語句可以使用LIMIT關(guān)鍵字進(jìn)行分頁,來保證我們每次查詢只拿符合需求的數(shù)據(jù)條數(shù)。剛剛也提到過ES也支持分頁,默認(rèn)每頁有10條數(shù)據(jù)。

語法

在搜索URL中可以使用size參數(shù)指定頁大小,from應(yīng)跳過的結(jié)果集條數(shù)。

請求信息:

[http[s]://]{host}:{port}/[{index}/[{type}/]]_search[?[size={size}][[&]from={from}]]
示例

不使用任何過濾條件搜索blogs索引type類型下的所有文檔,指定頁大小為2,從第跳過1條結(jié)果。

請求信息:

http://ubuntu:9200/blogs/articles/_search?size=2&from=1

響應(yīng)信息請自行演示。

多索引和類型

如果你需要在一個或多個特殊的索引并且在一個或者多個特殊的類型中進(jìn)行搜索。我們可以通過在URL中指定特殊的索引和類型達(dá)到這種效果,下面舉例說明如何使用多索引或多類型。
在所有的索引中搜索所有的類型

http://ubuntu:9200/_search

在 blogs 索引中搜索所有的類型

http://ubuntu:9200/blogs/_search

在 blogs 和 pictures 索引中搜索所有的文檔

http://ubuntu:9200/blogs,pictures/_search

在任何以 b 或者 p 開頭的索引中搜索所有的類型

http://ubuntu:9200/b*,g*/_search

在 blogs 索引中搜索 aiticles 類型

http://ubuntu:9200/blogs/articles/_search

在 blogs 和 pictures 索引中搜索 articles 和 a_images 類型的文檔

http://ubuntu:9200/blogs,pictures/articles,a_images/_search

在所有的索引中搜索 articles 和 a_images 類型的文檔

http://ubuntu:9200/_all/articles,a_images/_search

當(dāng)在單一的索引下進(jìn)行搜索的時候,Elasticsearch 轉(zhuǎn)發(fā)請求到索引的每個分片中,可以是主分片也可以是副本分片,然后從每個分片中收集結(jié)果。多索引搜索恰好也是用相同的方式工作的,只是會涉及到更多的分片。

多個搜索條件

剛剛介紹的條件搜索只能使用一個搜索條件,而我們一般的業(yè)務(wù)都需要更為復(fù)雜的搜索條件。

_all字段

在 blogs/aiticles 中搜索“為為”的相關(guān)信息,注意該搜索中并未指定“為為”屬于哪個字段。

http://ubuntu:9200/blogs/_search?q=為為
同時搜索多個字段

在 blogs/aiticles中搜索author包含"為為", title包含"ES"的信息。

http://ubuntu:9200/blogs/articles/_search?q=+title:ES自動生成id索引 +author:為為 
  • 前綴表示必須與查詢條件匹配。類似地, -前綴表示一定不與查詢條件匹配。沒有 + 或者 -的所有其他條件都是可選的——匹配的越多,文檔就越相關(guān)。在存在多個條件時,如果沒有明確使用default_operator=AND指定多個條件的關(guān)系為AND,則多個條件的關(guān)系為OR。
同一個字段下多種可能性

在 blogs/aiticles中搜索author包含"為為",tags為"java"或"編碼"的信息。

http://ubuntu:9200/blogs/articles/_search?q=+tags:(java 研發(fā))  +author:為為

在 blogs/aiticles中搜索author包含"為為",tags為"java"或"編碼"的信息。

http://ubuntu:9200/blogs/articles/_search?q=+tags:(java 研發(fā))  +author:為為&default_operator=AND

總結(jié)

經(jīng)過本文示例我們可以看出ES不僅可以作為一個NoSQL數(shù)據(jù)庫,存儲格式化的JSON數(shù)據(jù),其更強(qiáng)大的功能在于搜索。ES不僅會存儲文檔,文檔中的每個字段都將被索引并且可以被查詢 。不僅如此,在簡單查詢時,Elasticsearch 可以使用 所有(all)索引字段,快度返回結(jié)果,我們甚至不必指定具體要搜索哪個字段就。

總之ES的搜索可以完成以下任務(wù):

  • 在結(jié)構(gòu)化的數(shù)據(jù)(JSON)中使用結(jié)構(gòu)化查詢。
  • 全文檢索。

輕量級搜索雖然簡單方便,但其也有缺點:

  • 當(dāng)查詢字符串中很小的語法錯誤,像 - , : , / 或者 " 不匹配等,將會返回錯誤而不是搜索結(jié)果。
  • 允許任何用戶在索引的任意字段上執(zhí)行可能較慢且重量級的查詢,這可能會暴露隱私信息,甚至將集群拖垮。

基于以上兩點原因,不推薦向用戶直接開放輕量級搜索功能,一般情況下只在開發(fā)調(diào)試中使用。

引用

本文是我在學(xué)習(xí)使用ES時的筆記,在本文的寫過過程中參考了大量其它資料,有些材料來源于網(wǎng)絡(luò),我由衷的表示感謝,但由于原作者不明,恕不能一一記述。

  1. Elasticsearch 權(quán)威指南.——https://www.elastic.co/
  2. Elasticsearch技術(shù)解析與實戰(zhàn)/朱林編著.——北京:機(jī)械工業(yè)出版社,2016.12(數(shù)據(jù)分析與決策技術(shù)叢書)

關(guān)于

本項目和文檔中所用的內(nèi)容僅供學(xué)習(xí)和研究之用,轉(zhuǎn)載或引用時請指明出處。如果你對文檔有疑問或問題,請在項目中給我留言或發(fā)email到
weiwei02@vip.qq.com 我的github:
https://github.com/weiwei02/ 我相信技術(shù)能夠改變世界 。

鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容