ElasticSearch的查詢(二)

一、Query String search

  添加測試數據

PUT test_search
{
  "mappings": {
    "test_type": {
      "properties": {
        "dname": {
          "type": "text",
          "analyzer": "standard"
        },
        "ename": {
          "type": "text",
          "analyzer": "standard"
        },
        "eage": {
          "type": "long"
        },
        "hiredate": {
          "type": "date"
        },
        "gender": {
          "type": "keyword"
        }
      }
    }
  }
}

POST test_search/test_type/_bulk
{"index":{}}
{"dname":"Sales Department","ename":"張三","eage":20,"hiredate":"2019-01-01","gender":"男性"}
{"index":{}}
{"dname":"Sales Department","ename":"李四","eage":21,"hiredate":"2019-02-01","gender":"男性"}
{"index":{}}
{"dname":"Development Department","ename":"王五","eage":23,"hiredate":"2019-01-03","gender":"男性"}
{"index":{}}
{"dname":"Development Department","ename":"趙六","eage":26,"hiredate":"2018-01-01","gender":"男性"}
{"index":{}}
{"dname":"Development Department","ename":"韓梅梅","eage":24,"hiredate":"2019-03-01","gender":"女性"}
{"index":{}}
{"dname":"Development Department","ename":"錢虹","eage":29,"hiredate":"2018-03-01","gender":"女性"}
View Code

  search的參數都是類似http請求頭中的字符串參數提供搜索條件的

  GET [/index_name/type_name/]_search[?parameter_name=parameter_value&...]

1,全搜索

  timeout參數:是超時時長定義。代表每個節點上的每個shard執行搜索時最多耗時多久。不會影響響應的正常返回。只會影響返回響應中的數據數量。

  如:索引a中,有10億數據。存儲在5個shard中,假設每個shard中2億數據,執行全數據搜索的時候,需要耗時1000毫秒。定義timeout爲10毫秒,代表的是shard執行10毫秒,搜索出多少數據,直接返回。

  在商業項目中,是禁止全數據搜索的。必須指定搜索的索引,類型和關鍵字。如果沒有指定索引或類型,則代表開發目的不明確,需要重新做用例分析。如果沒有關鍵字,稱爲索引內全搜索,也叫魔鬼搜索。

  GET [索引名/類型名/]_search?timeout=10ms

結果返回:

{
  "took": 144, #請求耗時多少毫秒
  "timed_out": false, #是否超時。默認情況下沒有超時機制,也就是客戶端等待ElasticSearch搜索結束(無論執行多久),提供超時機制的話,ElasticSearch則在指定時長內處理搜索,在指定時長結束的時候,將搜索的結果直接返回(無論是否搜索結束)。指定超時的方式是傳遞參數,參數單位是:毫秒-ms。秒-s。分鐘-m。
  "_shards": {
    "total": 1, #請求發送到多少個shard上
    "successful": 1,#成功返回搜索結果的shard
    "skipped": 0, #停止服務的shard
    "failed": 0 #失敗的shard
  },
  "hits": {
    "total": 1, #返回了多少結果
    "max_score": 1, #搜索結果中,最大的相關度分數,相關度越大分數越高,_score越大,排位越靠前。
    "hits": [ #搜索到的結果集合,默認查詢前10條數據。
      {
        "_index": "test_index", #數據所在索引
        "_type": "my_type", #數據所在類型
        "_id": "1", #數據的id
        "_score": 1, #數據的搜索相關度分數
        "_source": { # 數據的具體內容。
          "field": "value"
        }
      }
    ]
  }
}

2,multi index搜索

  所謂的multi-index就是從多個index中搜索數據。相對使用較少,只有在複合數據搜索的時候,可能出現。一般來說,如果真使用複合數據搜索,都會使用_all。

  如:搜索引擎中的無條件搜索。(現在的應用中都被屏蔽了。使用的是默認搜索條件,執行數據搜索。 如: 電商中的搜索框默認值, 搜索引擎中的類別)

  無條件搜索,在搜索應用中稱爲“魔鬼搜索”,代表的是,搜索引擎會執行全數據檢索,效率極低,且對資源有非常高的壓力。

GET _search #搜索所有的索引
GET 索引名1,索引名2/_search # 搜索多個index中的數據
GET 索引名/類型名/_search # 所屬一個index中type的數據
GET prefix_*/_search # 通配符搜索
GET *_suffix/_search
GET 索引名1,索引名2/類型名/_search # 搜索多個index中type的數據
GET _all/_search  # _all代表所有的索引

3,條件搜索

  query string search 搜索是通過HTTP請求的請求頭傳遞參數的,默認的HTTP請求頭字符集是ISO-8859-1,請求頭傳遞中文會有亂碼。

  GET 索引名/_search?q=字段名:搜索條件

4,分頁搜索

  默認情況下,ElasticSearch搜索返回結果是10條數據。從第0條開始查詢

  GET 索引名/_search?from=0&size=10 # from 從第幾行開始查詢,行號從0開始。

5,+/-搜索

語法:

GET 索引名/_search?q=字段名:條件   #不加+/-默認使用的是+
GET 索引名/_search?q=+字段名:條件
GET 索引名/_search?q=-字段名:條件

  + :和不定義符號含義一樣,就是搜索指定的字段中包含keywords的數據,默認。

  - : 與+符號含義相反,就是搜索指定的字段中不包含keywords的數據。

6,排序

  GET 索引名/_search?sort=字段名:排序規則

案例:

GET test_search/_search?sort=eage:asc
GET test_search/_search?sort=eage:desc
GET test_search/_search?sort=gender:desc,eage:desc

二、DSL

  DSL - Domain Specified Language , 特殊領域的語言。

  請求參數是請求體傳遞的。在ElasticSearch中,請求體的字符集默認爲UTF-8。

語法:

GET 索引名/_search
{
   "command":{ "parameter_name" : "parameter_value"}
}

1,查詢所有

GET 索引名/_search
{
   "query" : { "match_all" : {} }
}

2,match search

  全文檢索。要求查詢條件拆分後的任意詞條具體數據匹配就算搜索結果。

GET 索引名/_search
{
  "query": {
    "match": {
      "字段名": "搜索條件"
    }
  }
}

3,phrase search

  短語檢索。要求查詢條件必須和具體數據完全匹配纔算搜索結果。其特徵是:1-搜索條件不做任何分詞解析;2-在搜索字段對應的倒排索引(正排索引)中進行精確匹配,不再是簡單的全文檢索。

GET 索引名/_search
{
  "query": {
    "match_phrase": {
      "字段名": "搜索條件"
    }
  }
}

4,range

  範圍檢索

GET 索引名/類型名/_search
{
  "query" : {
    "range" : {
      "字段名" : {
        "gt" : 搜索條件1, 
        "lte" : 搜索條件2
      }
    }
  }
}    

5,term

  詞組搜索。忽略搜索條件分詞,在ElasticSearch倒排索引中進行精確匹配。

GET 索引名/類型名/_search
{
  "query" : {
    "term" : {
      "字段名": "搜索條件"
    }
  }
}

GET 索引名/類型名/_search
{
  "query" : {
    "terms" : {
      "字段名": ["搜索條件1", "搜索條件2"]
    }
  }
}
  • term是將傳入的文本原封不動地(不分詞)拿去查詢
  • match會對輸入進行分詞處理後再去查詢,部分命中的結果也會按照評分由高到低顯示出來。
  • match_phrase是按短語查詢,只有存在這個短語的文檔纔會被顯示出來。會對傳入的文本進行分詞,但是必須完全匹配並且順序相同

6,多條件must、should、must_not

  • must數組中的多個條件必須同時滿足
  • must_not數組中的多個條件必須都不滿足
  • should數組中的多個條件有任意一個滿足即可。
GET 索引名/類型名/_search
{
  "query": {
    "bool": {
      "must": [ #數組中的多個條件必須同時滿足
        {
          "range": {
            "字段名": {
              "lt": 條件
            }
          }
        }
      ],
      "must_not":[ #數組中的多個條件必須都不滿足
        {
          "match": {
            "字段名": "條件"
          }
        },
        {
          "range": {
            "字段名": {
              "gte": "搜索條件"
            }
          }
        }
      ],
      "should": [# 數組中的多個條件有任意一個滿足即可。
        {
          "match": {
            "字段名": "條件"
          }
        },
        {
          "range": {
            "字段名": {
              "gte": "搜索條件"
            }
          }
        }
      ]
    }
  }
}

7,排序

  在ElasticSearch的搜索中,默認是使用相關度分數實現排序的。可以通過搜索語法實現定製化排序。

GET 索引名/類型名/_search
{
  "query": {
    [搜索條件]
  },
  "sort": [
    {
      "字段名1": {
        "order": "asc"
      }
    },
    {
      "字段名2": {
        "order": "desc"
      }
    }
  ]
}

  注意:在ElasticSearch中,如果使用text類型的字段作爲排序依據,會有問題。ElasticSearch需要對text類型字段數據做分詞處理。如果使用text類型字段做排序,ElasticSearch給出的排序結果未必友好,畢竟分詞後,先使用哪一個單詞做排序都是不合理的。所以ElasticSearch中默認情況下不允許使用text類型的字段做排序,如果需要使用字符串做結果排序,則可使用keyword類型字段作爲排序依據,因爲keyword字段不做分詞處理。

8,分頁

  DSL分頁也是使用from和size實現的。

GET 索引名稱/_search
{
  "query":{
    "match_all":{}
},
"from": 起始下標,
"size": 查詢記錄數
}

9,高亮

  在搜索中,經常需要對搜索關鍵字做高亮顯示,這個時候就可以使用highlight語法。

GET 索引名/_search
{
  "query": {
    "match": {
      "字段名": "條件"
    }
  },
  "highlight": {
    "fields": {
      "要高亮顯示的字段名": {
        "fragment_size": 5, #每個分段長度,默認20
        "number_of_fragments": 1 #返回多少個分段,默認3
      }
    },
    "pre_tags": ["前綴"], 
    "post_tags": ["後綴"] 
  }
}

案例:

GET test_search/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "dname": "Development department"
          }
        },
        {
          "match": {
            "gender": "男性"
          }
        }
      ]
    }
  },
  "highlight": {
    "fields": {
      "dname": {
        "fragment_size": 20,
        "number_of_fragments": 1
      },
      "gender": {
        "fragment_size": 20,
        "number_of_fragments": 1
      }
    },
    "pre_tags": [
      "<span style='color:red'>"
    ],
    "post_tags": [
      "</span>"
    ]
  },
  "from": 2,
  "size": 2
}

10,聚合查詢

語法:

"aggs": {
    "NAME": {# 指定結果的名稱
      "AGG_TYPE": {# 指定具體的聚合方法,
        TODO: # 聚合體內製定具體的聚合字段
      }
    },
    "NAME": {# 指定結果的名稱
      "AGG_TYPE": {# 指定具體的聚合方法,
        TODO: # 聚合體內製定具體的聚合字段
      }
    }
 }

  

三、SpringDataElasticsearch

  源碼:cloud-es

1,添加pom文件

<dependency>
    <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

2,修改applicaiton配置

#低版本使用5.x,注意使用的springdata的版本與es是否對應
spring.data.elasticsearch.cluster-name=es5-cluster
spring.data.elasticsearch.cluster-nodes= hadoop208:9300,hadoop209:9300
#高版本使用6.x
spring.elasticsearch.rest.uris=http://hadoop208:9200,http://hadoop209:9200

3,創建實體

  案例:Item對象

  • @Document指定實體類和索引對應關係@Id 指定主鍵
    • indexName:索引名稱
    • type: 索引類型(不加會給默認,es7之後刪除)
    • shards: 主分片數量,默認5
    • replicas:複製分片數量,默認1
  • @Field指定普通屬性
    • type: 對應Elasticsearch中屬性類型。使用FiledType枚舉可以快速獲取。測試發現沒有type屬性可能出現無法自動創建類型問題,所以一定要有type屬性。
    • text類型能被分詞
    • keywords不能被分詞
    • index: 是否創建索引。作爲搜索條件時index必須爲true
    • analyzer:指定分詞器類型。
    • fielddata:指定是否爲text類型字段創建正向索引。默認爲false,設置爲true則可以使用此字段排序

4,使用方式

  案例:ItemTest

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章