Elastic Search快速上手(3):搜索

前言

存儲好數據以後,即可經過RESTful API進行搜索。html

詳細文檔可參考:
--簡單搜索https://www.elastic.co/guide/cn/elasticsearch/guide/cn/search.html
--深刻搜索https://www.elastic.co/guide/cn/elasticsearch/guide/cn/search-in-depth.htmlpython

注:對前文的一個補充,可使用analyze來查看分詞器的分詞結果。算法

GET _analyze
{
  "analyzer": "ik_smart",
  "text":"數據結構算法熟悉"
}

分詞結果:django

{
  "tokens": [
    {
      "token": "數據結構",
      "start_offset": 0,
      "end_offset": 4,
      "type": "CN_WORD",
      "position": 0
    },
    {
      "token": "算法",
      "start_offset": 4,
      "end_offset": 6,
      "type": "CN_WORD",
      "position": 1
    },
    {
      "token": "熟悉",
      "start_offset": 6,
      "end_offset": 8,
      "type": "CN_WORD",
      "position": 2
    }
  ]
}

基本搜索

請求路徑

搜索使用GET方式,GET請求的路徑中,能夠包含目標索引、類型和文檔 id。數據結構

/_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 類型

輕量搜索

能夠直接在請求url中,附加搜索關鍵詞。
例如,查詢在 tweet 類型中 tweet 字段包含 elasticsearch 單詞的全部文檔:
GET _all/tweet/_search?q=tweet:elasticsearch
但這種方式當條件較爲複雜時,url會很難讀。elasticsearch

請求體查詢

形如:(注,有時GET不支持帶請求體,所以這裏的GET請求也可換成POST)ide

GET _search
{
    "query": {
        "match_all": {}
    }
}

match查詢

例如,查找title字段中含有python的:ui

GET test/_search
{
  "query":{
    "match":{
      "title":"python"
    }
  }
}

返回結果:url

{
  "took": 48, # 耗時48ms
  "timed_out": false, # 未超時
  "_shards": {
    "total": 5, # 共有5個分片進行查詢
    "successful": 5, # 5個分片成功查詢
    "failed": 0
  },
  "hits": { # 一共有3條知足條件的記錄
    "total": 3,
    "max_score": 0.45203948, # 最高得分
    "hits": [ # 如下爲結果集
      {
        "_index": "test",
        "_type": "job",
        "_id": "AV3LXb9wdmPltg3H8bEu",
        "_score": 0.45203948,
        "_source": {
          "title": "python打造推薦引擎系統",
          "company_name": "阿里巴巴科技公司",
          "desc": "熟悉推薦引擎的原理以及算法,掌握C語言",
          "comments": 60,
          "add_time": "2016-10-20"
        }
      }#略
      ]
  }
}

注意code

若是在一個精確字段上面使用match,則會精確匹配,好比在數字或者keyword的字段上使用。若是是text類型,則數據和查詢語句都會通過分詞器的處理。

例如,若是標題中爲python,而查詢詞爲大寫Python,若通過ik分詞,都會被轉換爲小寫,所以仍然能查出;但若是此title字段未經分詞,而是keyword類型的話,則大小寫不匹配,就沒法查出。

此外,match中只能指定一個查詢字段。

term查詢

區別是term對於查詢詞不會進行分詞,必須精確徹底匹配。

GET test/_search
{
  "query":{
    "term":{
      "title":"python打造"
    }
  }
}

terms查詢

可指定多個關鍵詞進行term查詢,知足其中一個關鍵詞便可。

GET test/_search
{
  "query":{
    "terms":{
      "title":["python打造","django"]
    }
  }
}

match_all查詢

最簡單的,查找全部。

GET test/_search
{
 "query": {
   "match_all": {}
 }
}

match_phrase查詢

在match查詢中,若是對text字段指定了像「python教程」這樣的查詢詞,會進行分詞,包含python或教程的結果都會被查詢出來。而match_phrase也會進行分詞,可是隻有所有包含這些詞的結果會被查詢出來。

GET test/_search
{
  "query":{
    "match_phrase": {
      "title":{
        "query":"python系統",
        "slop":6
      }
    }
  }
}

slop的含義是拆分出來的詞之間的最大間距。若超出此間距,就算都包含這些詞,也不會返回。

multi_match查詢

match查詢只能指定一個字段,而multi_match能夠指定多個字段。

GET test/_search
{
  "query":{
    "multi_match": {
      "query":"python",
      "fields":["title^3","desc"]
    }
  }
}

上面語句是同時在title和desc中查詢python關鍵詞。注意到^3,是指定權重,title字段的權重是desc的三倍。

查詢範圍

查詢comments中大於5小於等於60的數據:

GET test/_search
{
  "query":{
    "range":{
      "comments":{
        "gt":5,
        "lte":60
      }
    }
  }
}

查詢時間大於17-4-1並且小於等於當前:

GET test/_search
{
  "query":{
    "range":{
      "add_time":{
        "gt":"2017-04-01",
        "lte":"now",
        "boost":2.0
      }
    }
  }
}

(boost是權重,無關緊要,別的地方也能夠用)

通配符查詢

查詢pyt*n:

GET test/_search
{
  "query":{
      "wildcard":{
        "title":{
          "value":"pyt*n",
          "boost":2.0
        }
      }
  }
}

查詢結果分頁

能夠進行查詢結果的分頁,指定從第幾個開始,取幾個。

GET test/_search
{
  "query":{
    "match":{
      "title":"python"
    }
  },
  "from":0,
  "size":2
}

只返回部分字段

仍是能夠經過_source指定返回哪些字段。

GET test/_search
{
  "_source": ["title","company_name"], 
  "query":{
    "match":{
      "title":"python"
    }
  }
}

返回結果排序

對comments字段按照asc升序排列(desc爲降序):

GET test/_search
{
  "query":{
    "match":{
      "title":"python"
    }
  },
  "sort":{
    "comments":{
      "order":"asc"
    }
  }
}

bool查詢

查詢參數

bool查詢將多查詢組合在一塊兒,它包含如下四種參數:
must
文檔 必須 匹配這些條件才能被包含進來。
must_not
文檔 必須不 匹配這些條件才能被包含進來。
should
若是知足這些語句中的任意語句,將增長 _score ,不然,無任何影響。它們主要用於修正每一個文檔的相關性得分。
filter
必須 匹配,但它以不評分、過濾模式來進行。這些語句對評分沒有貢獻,只是根據過濾標準來排除或包含文檔。

簡單過濾

在bool中可指定filter進行過濾。
如,使用term精確匹配出salary爲20的文檔:

GET test2/job/_search
{
  "query":{
    "bool":{
      "filter":{
        "term":{
          "salary":20
        }
      }
    }
  }
}

若是想過濾多個值,能夠用terms。

組合查詢

靈活運用各類組合過濾查詢。例如,下面的查詢,是{salary不能爲30}而且{salary爲20 或者 title匹配python}

GET test2/job/_search
{
  "query":{
    "bool":{
      "should":[
        {"term":{"salary":20}},
        {"match":{"title":"python"}}
      ],
      "must_not":{
        "term":{"salary":30}
      }
    }
  }
}

嵌套查詢

bool可進行嵌套。下面的例子,外層should並列兩個條件或,要麼標題含有python,要麼必須知足標題精確匹配django並且salary精確匹配30.

GET test2/job/_search
{
  "query":{
    "bool":{
      "should":[
        {"match":{"title":"python"}},
        {"bool":{
          "must":[
            {"term":{"title":"django"}},
            {"term":{"salary":30}}
            ]
        }}
      ]
    }
  }
}

exists

用於查詢某個字段是否存在或爲null。
下面例子中,前者篩選出存在title字段的文檔,後者則反之。

GET test2/job2/_search
{
  "query":{
    "bool":{
      "filter":{
        "exists": {
          "field": "title"
        }
      }
    }
  }
}

GET test2/job2/_search
{
  "query":{
    "bool":{
      "must_not":{
        "exists": {
          "field": "title"
        }
      }
    }
  }
}


通過上面的介紹,基本整理了es的搜索中的經常使用方法,能知足最基礎的搜索使用。更詳細的搜索,請參閱文檔。

相關文章
相關標籤/搜索