1、基礎(chǔ)概念
| 概念 | 說明 |
|---|---|
| 索引庫(indices) | indices是index的復(fù)數(shù),代表許多的索引, |
| 類型(type) | 類型是模擬mysql中的table概念,一個(gè)索引庫下可以有不同類型的索引,比如商品索引,訂單索引,其數(shù)據(jù)格式不同。不過這會(huì)導(dǎo)致索引庫混亂,因此未來版本中會(huì)移除這個(gè)概念 |
| 文檔(document) | 存入索引庫原始的數(shù)據(jù)。比如每一條商品信息,就是一個(gè)文檔 |
| 字段(field) | 文檔中的屬性 |
| 映射配置(mappings) | 字段的數(shù)據(jù)類型、屬性、是否索引、是否存儲(chǔ)等特性 |
- 索引集(Indices,index的復(fù)數(shù)):邏輯上的完整索引
- 分片(shard):數(shù)據(jù)拆分后的各個(gè)部分
- 副本(replica):每個(gè)分片的復(fù)制
要注意的是:Elasticsearch本身就是分布式的,因此即便你只有一個(gè)節(jié)點(diǎn),Elasticsearch默認(rèn)也會(huì)對(duì)你的數(shù)據(jù)進(jìn)行分片和副本操作,當(dāng)你向集群添加新數(shù)據(jù)時(shí),數(shù)據(jù)也會(huì)在新加入的節(jié)點(diǎn)中進(jìn)行平衡。
2、索引操作
創(chuàng)建索引
PUT /索引庫名
{
"settings": {
"number_of_shards": 3, //分片數(shù)量
"number_of_replicas": 2 //副本數(shù)量
}
}
查看索引
GET /索引庫名
GET _cat/indices 查看所有索引
刪除索引
DELETE /索引庫名
3、映射字段
創(chuàng)建映射字段
PUT /索引庫名/_mapping
{
"properties": {
"字段名": {
"type": "類型",
"index": true,
"store": true,
"analyzer": "分詞器"
}
}
}
- 字段名:任意填寫 ,可以指定許多屬性,例如:
- type:類型,可以是text、long、short、date、integer、object等
- index:是否索引,默認(rèn)為true
- store:是否存儲(chǔ),默認(rèn)為false
- analyzer:分詞器,這里的ik_max_word即使用ik分詞器
PUT xiaomi/_mapping
{
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word"
},
"images": {
"type": "keyword",
"index": "false"
},
"price": {
"type": "float"
}
}
}
查看映射關(guān)系
GET /索引庫名/_mapping
字段屬性詳解
- String類型,又分兩種:
- text:可分詞,不可參與聚合
- keyword:不可分詞,數(shù)據(jù)會(huì)作為完整字段進(jìn)行匹配,可以參與聚合
Numerical:數(shù)值類型,分兩類 - 基本數(shù)據(jù)類型:long、interger、short、byte、double、float、half_float
- 浮點(diǎn)數(shù)的高精度類型:scaled_float
- 需要指定一個(gè)精度因子,比如10或100。elasticsearch會(huì)把真實(shí)值乘以這個(gè)因子后存儲(chǔ),取出時(shí)再還原。
- Date:日期類型
- elasticsearch可以對(duì)日期格式化為字符串存儲(chǔ),但是建議我們存儲(chǔ)為毫秒值,存儲(chǔ)為long,節(jié)省空間。
4、數(shù)據(jù)的增刪改
4.1隨機(jī)生成id
POST /xiaomi/_doc
{
"title":"小米手機(jī)",
"images":"http://image.leyou.com/12479122.jpg",
"price":2699.00
}
4.2自定義id
POST /xiaomi/_doc/2
{
"title":"大米手機(jī)",
"images":"http://image.leyou.com/12479122.jpg",
"price":2899.00
}
4.3新增數(shù)據(jù)時(shí)使用在配置映射之外的字段
額外添加了stock庫存,和saleable是否上架兩個(gè)字段
POST /xiaomi/_doc/3
{
"title":"超米手機(jī)",
"images":"http://image.leyou.com/12479122.jpg",
"price":2899.00,
"stock": 200,
"saleable":true
}
結(jié)果
{
"_index": "xiaomi",
"_type": "goods",
"_id": "3",
"_version": 1,
"_score": 1,
"_source": {
"title": "超米手機(jī)",
"images": "http://image.leyou.com/12479122.jpg",
"price": 2899,
"stock": 200,
"saleable": true
}
}
Elasticsearch非常智能,你不需要給索引庫設(shè)置任何mapping映射,它也可以根據(jù)你輸入的數(shù)據(jù)來判斷類型,動(dòng)態(tài)添加數(shù)據(jù)映射。
4.4修改數(shù)據(jù)
把剛才新增的請(qǐng)求方式改為PUT,就是修改了。不過修改必須指定id,
- id對(duì)應(yīng)文檔存在,則修改
- id對(duì)應(yīng)文檔不存在,則新增
PUT /xiaomi/_doc/3
{
"title":"超大米手機(jī)",
"images":"http://image.leyou.com/12479122.jpg",
"price":3899.00,
"stock": 100,
"saleable":true
}
4.5刪除數(shù)據(jù)
DELETE /索引庫名/類型名/id值
5、查詢數(shù)據(jù)
基礎(chǔ)語法
GET /索引庫名/_search
{
"query":{
"查詢類型":{
"查詢條件":"查詢條件值"
}
}
}
5.1查詢所有match_all
GET /xiaomi/_search
{
"query":{
"match_all": {}
}
}
結(jié)果
{
"took": 2, //查詢花費(fèi)時(shí)間,單位是毫秒
"timed_out": false, //是否超時(shí)
"_shards": { //分片信息
"total": 3,
"successful": 3,
"skipped": 0,
"failed": 0
},
"hits": { //搜索結(jié)果總覽對(duì)象
"total": 1, //搜索到的總條數(shù)
"max_score": 1, //所有結(jié)果中文檔得分的最高分
"hits": [ //搜索結(jié)果的文檔對(duì)象數(shù)組,每個(gè)元素是一條搜索到的文檔信息
{
"_index": "xiaomi", //索引庫
"_type": "goods", //文檔類型
"_id": "2", //文檔id
"_score": 1, //文檔得分
"_source": { //文檔的源數(shù)據(jù)
"title": "大米手機(jī)",
"images": "http://image.leyou.com/12479122.jpg",
"price": 2899
}
}
}
]
}
}
5.2匹配查詢match
or關(guān)系
match類型查詢,會(huì)把查詢條件進(jìn)行分詞,然后進(jìn)行查詢,多個(gè)詞條之間是or的關(guān)系
GET /xiaomi/_search
{
"query":{
"match":{
"title":"小米電視"
}
}
}
and關(guān)系
- 即對(duì)關(guān)鍵詞進(jìn)行分詞以后,查詢包括所有分詞條件的數(shù)據(jù)
GET /xiaomi/_search
{
"query":{
"match": {
"title": {
"query": "小米電視",
"operator": "and"
}
}
}
}
or和and如何選擇
在 or 與 and 間二選一有點(diǎn)過于非黑即白。 如果用戶給定的條件分詞后有 5 個(gè)查詢?cè)~項(xiàng),想查找只包含其中 4 個(gè)詞的文檔,該如何處理?將 operator 操作符參數(shù)設(shè)置成 and 只會(huì)將此文檔排除。
有時(shí)候這正是我們期望的,但在全文搜索的大多數(shù)應(yīng)用場景下,我們既想包含那些可能相關(guān)的文檔,同時(shí)又排除那些不太相關(guān)的。換句話說,我們想要處于中間某種結(jié)果。
match查詢支持minimum_should_match最小匹配參數(shù), 這讓我們可以指定必須匹配的詞項(xiàng)數(shù)用來表示一個(gè)文檔是否相關(guān)。我們可以將其設(shè)置為某個(gè)具體數(shù)字,更常用的做法是將其設(shè)置為一個(gè)百分?jǐn)?shù),因?yàn)槲覀儫o法控制用戶搜索時(shí)輸入的單詞數(shù)量
GET /xiaomi/_search
{
"query":{
"match":{
"title":{
"query":"小米曲面電視",
"minimum_should_match": "75%"
}
}
}
}
5.3多字段查詢multi_match
multi_match與match類似,不同的是它可以在多個(gè)字段中查詢
GET /xiaomi/_search
{
"query":{
"multi_match": {
"query": "小米",
"fields": [ "title", "subTitle" ]
}
}
}
5.4 詞條匹配term
term 查詢被用于精確值 匹配,這些精確值可能是數(shù)字、時(shí)間、布爾或者那些未分詞的字符串
GET /xiaomi/_search
{
"query":{
"term":{
"price":2699.00
}
}
}
5.5 多詞條精確匹配terms
terms 查詢和 term 查詢一樣,但它允許你指定多值進(jìn)行匹配。如果這個(gè)字段包含了指定值中的任何一個(gè)值,那么這個(gè)文檔滿足條件:
GET /xiaomi/_search
{
"query":{
"terms":{
"price":[2699.00,2899.00,3899.00]
}
}
}
6、查詢結(jié)果過濾
默認(rèn)情況下,elasticsearch在搜索的結(jié)果中,會(huì)把文檔中保存在_source的所有字段都返回
如果我們只想獲取其中的部分字段,我們可以添加_source的過濾
6.1直接指定字段
GET /xiaomi/_search
{
"_source": ["title","price"],
"query": {
"term": {
"price": 2699
}
}
}
6.2指定includes和excludes
- includes:來指定想要顯示的字段
- excludes:來指定不想要顯示的字段
GET /xiaomi/_search
{
"_source": {
"includes":["title","price"]
},
"query": {
"term": {
"price": 2699
}
}
}
7、高級(jí)查詢
7.1 布爾組合 bool
bool把各種其它查詢通過must(與)、must_not(非)、should(或)的方式進(jìn)行組合
GET /xiaomi/_search
{
"query":{
"bool":{
"must": { "match": { "title": "大米" }},
"must_not": { "match": { "title": "電視" }},
"should": { "match": { "title": "手機(jī)" }}
}
}
}
7.2 范圍查詢 range
range 查詢找出那些落在指定區(qū)間內(nèi)的數(shù)字或者時(shí)間
GET /xiaomi/_search
{
"query":{
"range": {
"price": {
"gte": 1000.0,
"lt": 2800.00
}
}
}
}
range查詢?cè)试S以下字符:
| 操作符 | 說明 |
|---|---|
| gt | 大于 |
| gte | 大于等于 |
| lt | 小于 |
| lte | 小于等于 |
7.3 模糊查詢 fuzzy
POST /heima/goods/4
{
"title":"iphone手機(jī)",
"images":"http://image.leyou.com/12479122.jpg",
"price":6899.00
}
fuzzy 查詢是 term 查詢的模糊等價(jià)。它允許用戶搜索詞條與實(shí)際詞條的拼寫出現(xiàn)偏差,但是偏差的編輯距離不得超過2:
GET /xiaomi/_search
{
"query": {
"fuzzy": {
"title": "iphona"
}
}
}
可以通過fuzziness來指定允許的編輯距離:
GET /xiaomi/_search
{
"query": {
"fuzzy": {
"title": {
"value":"iphona",
"fuzziness":1
}
}
}
}
7.4 過濾 filter
條件查詢中進(jìn)行過濾
所有的查詢都會(huì)影響到文檔的評(píng)分及排名。如果我們需要在查詢結(jié)果中進(jìn)行過濾,并且不希望過濾條件影響評(píng)分,那么就不要把過濾條件作為查詢條件來用。而是使用filter方式:
GET /xiaomi/_search
{
"query":{
"bool":{
"must":{ "match": { "title": "小米手機(jī)" }},
"filter":{
"range":{"price":{"gt":2000.00,"lt":3800.00}}
}
}
}
}
無查詢條件,直接過濾
如果一次查詢只有過濾,沒有查詢條件,不希望進(jìn)行評(píng)分,我們可以使用constant_score取代只有 filter 語句的 bool 查詢。在性能上是完全相同的,但對(duì)于提高查詢簡潔性和清晰度有很大幫助。
GET /xiaomi/_search
{
"query":{
"constant_score": {
"filter": {
"range":{"price":{"gt":2000.00,"lt":3000.00}}
}
}
}
7.5 排序 Sort
GET /xiaomi/_search
{
"query": {
"match": {
"title": "小米手機(jī)"
}
},
"sort": [
{
"price": {
"order": "desc"
}
}
]
}
多字段排序
GET /xiaomi/_search
{
"query":{
"bool":{
"must":{ "match": { "title": "小米手機(jī)" }},
"filter":{
"range":{"price":{"gt":200000,"lt":300000}}
}
}
},
"sort": [
{ "price": { "order": "desc" }},
{ "_score": { "order": "desc" }}
]
}