ES學(xué)習(xí)教程

前言

  • es是什么逢艘?
    es是基于Apache Lucene的開源分布式(全文)搜索引擎蒸绩,,提供簡單的RESTful API來隱藏Lucene的復(fù)雜性涩哟。
    es除了全文搜索引擎之外索赏,還可以這樣描述它:
    1、分布式的實(shí)時文件存儲贴彼,每個字段都被索引并可被搜索
    2潜腻、分布式的實(shí)時分析搜索引擎
    3、可以擴(kuò)展到成百上千臺服務(wù)器器仗,處理PB級結(jié)構(gòu)化或非結(jié)構(gòu)化數(shù)據(jù)融涣。

  • ES的數(shù)據(jù)組織類比

Relational DB Elasticsearch
數(shù)據(jù)庫(database) 索引(indices)
表(tables) types
行(rows) documents
字段(columns) fields
  • mac安裝ES
- 1、更新brew   
```brew update```
- 2精钮、安裝java1.8版本
```brew cask install homebrew/cask-versions/java8```
- 3威鹿、安裝ES
```brew install elasticsearch```
- 4、啟動本地ES
```brew services start elasticsearch```
- 5轨香、本地訪問9200端口查看ES安裝
```http://localhost:9200```
- 6忽你、安裝kibana
```Kibana是ES的一個配套工具,可以讓用戶在網(wǎng)頁中與ES進(jìn)行交互```
```brew install kibana```
- 7臂容、本地啟動kibana
```brew services start kibana```
- 8科雳、本地訪問5601端口進(jìn)入kibana交互界面
```http://localhost:5601```

一、 ES簡單的增刪改查

1脓杉、創(chuàng)建一篇文檔(有則修改糟秘,無則創(chuàng)建)

PUT test/doc/2
{
  "name":"wangfei",
  "age":27,
  "desc":"熱天還不讓后人不認(rèn)同"
}

PUT test/doc/1
{
  "name":"wangjifei",
  "age":27,
  "desc":"薩芬我反胃為范圍額"
}

PUT test/doc/3
{
  "name":"wangyang",
  "age":30,
  "desc":"點(diǎn)在我心內(nèi)的幾首歌"
}

2、查詢指定索引信息

GET test

3球散、 查詢指定文檔信息

GET test/doc/1
GET test/doc/2

4尿赚、查詢對應(yīng)索引下所有數(shù)據(jù)

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

5、刪除指定文檔

DELETE test/doc/3

6、刪除索引

DELETE test

7凌净、修改指定文檔方式

  • 修改時悲龟,不指定的屬性會自動覆蓋,只保留指定的屬性(不正確的修改指定文檔方式)
PUT test/doc/1
{
  "name":"王計(jì)飛"
}
  • 使用POST命令泻蚊,在id后面跟_update躲舌,要修改的內(nèi)容放到doc文檔(屬性)中(正確的修改指定文檔方式)
POST test/doc/1/_update
{
  "doc":{
    "desc":"生活就像 茫茫海上"
  }
}

二丑婿、ES查詢的兩種方式

1性雄、查詢字符串搜索

GET test/doc/_search?q=name:wangfei

2、結(jié)構(gòu)化查詢(單字段查詢,不能多字段組合查詢)

GET test/doc/_search
{
  "query":{
    "match":{
      "name":"wang"
    }
  }
}

三羹奉、match系列之操作

1秒旋、match系列之match_all (查詢?nèi)?

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

2、match系列之match_phrase(短語查詢)

準(zhǔn)備數(shù)據(jù)

PUT test1/doc/1
{
  "title": "中國是世界上人口最多的國家"
}
PUT test1/doc/2
{
  "title": "美國是世界上軍事實(shí)力最強(qiáng)大的國家"
}
PUT test1/doc/3
{
  "title": "北京是中國的首都"
}
查詢語句

GET test1/doc/_search
{
  "query":{
    "match":{
      "title":"中國"
    }
  }
}

>>>輸出結(jié)果
{
  "took" : 241,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 3,
    "max_score" : 0.68324494,
    "hits" : [
      {
        "_index" : "test1",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.68324494,
        "_source" : {
          "title" : "中國是世界上人口最多的國家"
        }
      },
      {
        "_index" : "test1",
        "_type" : "doc",
        "_id" : "3",
        "_score" : 0.5753642,
        "_source" : {
          "title" : "北京是中國的首都"
        }
      },
      {
        "_index" : "test1",
        "_type" : "doc",
        "_id" : "2",
        "_score" : 0.39556286,
        "_source" : {
          "title" : "美國是世界上軍事實(shí)力最強(qiáng)大的國家"
        }
      }
    ]
  }
}

通過觀察結(jié)果可以發(fā)現(xiàn)诀拭,雖然如期的返回了中國的文檔迁筛。但是卻把和美國的文檔也返回了,這并不是我們想要的耕挨。是怎么回事呢细卧?因?yàn)檫@是elasticsearch在內(nèi)部對文檔做分詞的時候,對于中文來說筒占,就是一個字一個字分的贪庙,所以,我們搜中國翰苫,中和國都符合條件止邮,返回,而美國的國也符合奏窑。而我們認(rèn)為中國是個短語导披,是一個有具體含義的詞。所以elasticsearch在處理中文分詞方面比較弱勢埃唯。后面會講針對中文的插件撩匕。但目前我們還有辦法解決,那就是使用短語查詢 用match_phrase
GET test1/doc/_search
{
  "query":{
    "match_phrase": {
      "title": "中國"
    }
  }
}

>>>查詢結(jié)果
{
  "took" : 10,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 0.5753642,
    "hits" : [
      {
        "_index" : "test1",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.5753642,
        "_source" : {
          "title" : "中國是世界上人口最多的國家"
        }
      },
      {
        "_index" : "test1",
        "_type" : "doc",
        "_id" : "3",
        "_score" : 0.5753642,
        "_source" : {
          "title" : "北京是中國的首都"
        }
      }
    ]
  }
}
我們搜索中國和世界這兩個指定詞組時墨叛,但又不清楚兩個詞組之間有多少別的詞間隔止毕。那么在搜的時候就要留有一些余地。這時就要用到了slop了巍实。相當(dāng)于正則中的中國.*?世界滓技。這個間隔默認(rèn)為0
GET test1/doc/_search
{
  "query":{
    "match_phrase": {
      "title": {
        "query": "中國世界",
        "slop":2
      }
    }
  }
}

>>>查詢結(jié)果
{
  "took" : 23,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.7445889,
    "hits" : [
      {
        "_index" : "test1",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.7445889,
        "_source" : {
          "title" : "中國是世界上人口最多的國家"
        }
      }
    ]
  }
}

3、match系列之match_phrase_prefix(最左前綴查詢)智能搜索--以什么開頭

數(shù)據(jù)準(zhǔn)備

PUT test2/doc/1
{
  "title": "prefix1",
  "desc": "beautiful girl you are beautiful so"
}

PUT test2/doc/2
{
  "title": "beautiful",
  "desc": "I like basking on the beach"
}
搜索特定英文開頭的數(shù)據(jù)
查詢語句

GET test2/doc/_search
{
  "query": {
    "match_phrase_prefix": {
      "desc": "bea"
    }
  }
}

>>>查詢結(jié)果()
{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 0.39556286,
    "hits" : [
      {
        "_index" : "test2",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.39556286,
        "_source" : {
          "title" : "prefix1",
          "desc" : "beautiful girl you are beautiful so"
        }
      },
      {
        "_index" : "test2",
        "_type" : "doc",
        "_id" : "2",
        "_score" : 0.2876821,
        "_source" : {
          "title" : "beautiful",
          "desc" : "I like basking on the beach"
        }
      }
    ]
  }
}

查詢短語
GET test2/doc/_search
{
  "query": {
    "match_phrase_prefix": {
      "desc": "you are bea"
    }
  }
}

>>>查詢結(jié)果
{
  "took" : 28,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.8630463,
    "hits" : [
      {
        "_index" : "test2",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.8630463,
        "_source" : {
          "title" : "prefix1",
          "desc" : "beautiful girl you are beautiful so"
        }
      }
    ]
  }
}

max_expansions 參數(shù)理解 前綴查詢會非常的影響性能棚潦,要對結(jié)果集進(jìn)行限制令漂,就加上這個參數(shù)。
GET test2/doc/_search
{
  "query": {
    "match_phrase_prefix": {
      "desc": {
        "query": "bea",
        "max_expansions":1
      }
    }
  }
}

4、match系列之multi_match(多字段查詢)

  • multi_match是要在多個字段中查詢同一個關(guān)鍵字 除此之外叠必,mulit_match甚至可以當(dāng)做match_phrase和match_phrase_prefix使用荚孵,只需要指定type類型即可
GET test2/doc/_search
{
  "query": {
    "multi_match": {
      "query": "beautiful",
      "fields": ["title","desc"]
    }
  }
}

>>查詢結(jié)果
{
  "took" : 43,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 0.39556286,
    "hits" : [
      {
        "_index" : "test2",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.39556286,
        "_source" : {
          "title" : "prefix1",
          "desc" : "beautiful girl you are beautiful so"
        }
      },
      {
        "_index" : "test2",
        "_type" : "doc",
        "_id" : "2",
        "_score" : 0.2876821,
        "_source" : {
          "title" : "beautiful",
          "desc" : "I like basking on the beach"
        }
      }
    ]
  }
}
  • 當(dāng)設(shè)置屬性 type:phrase 時 等同于 短語查詢
GET test1/doc/_search
{
  "query": {
    "multi_match": {
      "query": "中國",
      "fields": ["title"],
      "type": "phrase"
    }
  }
}

>>>查詢結(jié)果
{
  "took" : 47,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 0.5753642,
    "hits" : [
      {
        "_index" : "test1",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.5753642,
        "_source" : {
          "title" : "中國是世界上人口最多的國家"
        }
      },
      {
        "_index" : "test1",
        "_type" : "doc",
        "_id" : "3",
        "_score" : 0.5753642,
        "_source" : {
          "title" : "北京是中國的首都"
        }
      }
    ]
  }
}
  • 當(dāng)設(shè)置屬性 type:phrase_prefix時 等同于 最左前綴查詢
GET test2/doc/_search
{
  "query": {
    "multi_match": {
      "query": "bea",
      "fields": ["desc"],
      "type": "phrase_prefix"
    }
  }
}

>>查詢結(jié)果
{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 0.5753642,
    "hits" : [
      {
        "_index" : "test1",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.5753642,
        "_source" : {
          "title" : "中國是世界上人口最多的國家"
        }
      },
      {
        "_index" : "test1",
        "_type" : "doc",
        "_id" : "3",
        "_score" : 0.5753642,
        "_source" : {
          "title" : "北京是中國的首都"
        }
      }
    ]
  }
}

match 查詢相關(guān)總結(jié)

1、match:返回所有匹配的分詞纬朝。

2收叶、match_all:查詢?nèi)俊?/p>

3、match_phrase:短語查詢共苛,在match的基礎(chǔ)上進(jìn)一步查詢詞組判没,可以指定slop分詞間隔。

4隅茎、match_phrase_prefix:前綴查詢澄峰,根據(jù)短語中最后一個詞組做前綴匹配,可以應(yīng)用于搜索提示辟犀,但注意和max_expanions搭配撞秋。其實(shí)默認(rèn)是50.......

5舶治、multi_match:多字段查詢勾怒,使用相當(dāng)?shù)撵`活郊艘,可以完成match_phrase和match_phrase_prefix的工作。

四出嘹、ES的排序查詢

es 6.8.4版本中席楚,需要分詞的字段不可以直接排序,比如:text類型疚漆,如果想要對這類字段進(jìn)行排序酣胀,需要特別設(shè)置:對字段索引兩次,一次索引分詞(用于搜索)一次索引不分詞(用于排序)娶聘,es默認(rèn)生成的text類型字段就是通過這樣的方法實(shí)現(xiàn)可排序的闻镶。
GET test/doc/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ]
}

>>排序結(jié)果
{
  "took" : 152,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 3,
    "max_score" : null,
    "hits" : [
      {
        "_index" : "test",
        "_type" : "doc",
        "_id" : "3",
        "_score" : null,
        "_source" : {
          "name" : "wangyang",
          "age" : 30,
          "desc" : "點(diǎn)在我心內(nèi)的幾首歌"
        },
        "sort" : [
          30
        ]
      },
      {
        "_index" : "test",
        "_type" : "doc",
        "_id" : "2",
        "_score" : null,
        "_source" : {
          "name" : "wangfei",
          "age" : 27,
          "desc" : "熱天還不讓后人不認(rèn)同"
        },
        "sort" : [
          27
        ]
      },
      {
        "_index" : "test",
        "_type" : "doc",
        "_id" : "1",
        "_score" : null,
        "_source" : {
          "name" : "wangjifei",
          "age" : 27,
          "desc" : "生活就像 茫茫海上"
        },
        "sort" : [
          27
        ]
      }
    ]
  }
}
  • 升序排序
GET test/doc/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "age": {
        "order": "asc"
      }
    }
  ]
}

五、ES的分頁查詢

  • from:從哪開始查 size:返回幾條結(jié)果
GET test/doc/_search
{
  "query": {
    "match_phrase_prefix": {
      "name": "wang"
    }
  },
  "from": 0,
  "size": 1
}

>>查詢結(jié)果
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 3,
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "test",
        "_type" : "doc",
        "_id" : "2",
        "_score" : 0.2876821,
        "_source" : {
          "name" : "wangfei",
          "age" : 27,
          "desc" : "熱天還不讓后人不認(rèn)同"
        }
      }
    ]
  }
}

六丸升、ES的bool查詢 (must铆农、should)

  • must (must字段對應(yīng)的是個列表,也就是說可以有多個并列的查詢條件狡耻,一個文檔滿足各個子條件后才最終返回)
#### 單條件查詢
GET test/doc/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
          "name": "wangfei"
          }
        }
      ]
    }
  }
}

>>查詢結(jié)果
{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "test",
        "_type" : "doc",
        "_id" : "2",
        "_score" : 0.2876821,
        "_source" : {
          "name" : "wangfei",
          "age" : 27,
          "desc" : "熱天還不讓后人不認(rèn)同"
        }
      }
    ]
  }
}
#### 多條件組合查詢
GET test/doc/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "wanggfei"
          }
        },{
          "match": {
            "age": 25
          }
        }
      ]
    }
  }
}

>>查詢結(jié)果
{
  "took" : 21,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 0,
    "max_score" : null,
    "hits" : [ ]
  }
}

  • should (只要符合其中一個條件就返回)
GET test/doc/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
          "name": "wangjifei"
        }
        },{
          "match": {
            "age": 27
          }
        }
      ]
    }
  }
}

>>查詢結(jié)果
{
  "took" : 34,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 1.287682,
    "hits" : [
      {
        "_index" : "test",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 1.287682,
        "_source" : {
          "name" : "wangjifei",
          "age" : 27,
          "desc" : "生活就像 茫茫海上"
        }
      },
      {
        "_index" : "test",
        "_type" : "doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "name" : "wangfei",
          "age" : 27,
          "desc" : "熱天還不讓后人不認(rèn)同"
        }
      }
    ]
  }
}
  • must_not 顧名思義
GET test/doc/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "match": {
            "name": "wangjifei"
          }
        },{
          "match": {
            "age": 27
          }
        }
      ]
    }
  }
}

>>查詢結(jié)果
{
  "took" : 13,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "test",
        "_type" : "doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "name" : "wangyang",
          "age" : 30,
          "desc" : "點(diǎn)在我心內(nèi)的幾首歌"
        }
      }
    ]
  }
}
  • filter(條件過濾查詢墩剖,過濾條件的范圍用range表示gt表示大于、lt表示小于夷狰、gte表示大于等于岭皂、lte表示小于等于)
GET test/doc/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "wangjifei"
          }
        }
      ],
      "filter": {
        "range": {
          "age": {
            "gte": 10,
            "lt": 27
          }
        }
      }
    }
  }
}

>>查詢結(jié)果
{
  "took" : 33,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 0,
    "max_score" : null,
    "hits" : [ ]
  }
}

bool查詢總結(jié)

must:與關(guān)系,相當(dāng)于關(guān)系型數(shù)據(jù)庫中的 and沼头。

should:或關(guān)系爷绘,相當(dāng)于關(guān)系型數(shù)據(jù)庫中的 or书劝。

must_not:非關(guān)系,相當(dāng)于關(guān)系型數(shù)據(jù)庫中的 not土至。

filter:過濾條件购对。

range:條件篩選范圍。

gt:大于陶因,相當(dāng)于關(guān)系型數(shù)據(jù)庫中的 >骡苞。

gte:大于等于,相當(dāng)于關(guān)系型數(shù)據(jù)庫中的 >=楷扬。

lt:小于解幽,相當(dāng)于關(guān)系型數(shù)據(jù)庫中的 <。

lte:小于等于毅否,相當(dāng)于關(guān)系型數(shù)據(jù)庫中的 <=亚铁。

七、ES之查詢結(jié)果過濾

####準(zhǔn)備數(shù)據(jù)

PUT test3/doc/1
{
  "name":"顧老二",
  "age":30,
  "from": "gu",
  "desc": "皮膚黑螟加、武器長、性格直",
  "tags": ["黑", "長", "直"]
}
  • 現(xiàn)在吞琐,在所有的結(jié)果中捆探,我只需要查看name和age兩個屬性,提高查詢效率
GET test3/doc/_search
{
  "query": {
    "match": {
      "name": "顧"
    }
  },
  "_source": ["name","age"]
}

>>查詢結(jié)果
{
  "took" : 58,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "test3",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "name" : "顧老二",
          "age" : 30
        }
      }
    ]
  }
}

八、ES之查詢結(jié)果高亮顯示

  • ES的默認(rèn)高亮顯示
GET test3/doc/_search
{
  "query": {
    "match": {
      "name": "顧老二"
    }
  },
  "highlight": {
    "fields": {
      "name": {}
    }
  }
}

>>查詢結(jié)果
{
  "took" : 216,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.8630463,
    "hits" : [
      {
        "_index" : "test3",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.8630463,
        "_source" : {
          "name" : "顧老二",
          "age" : 30,
          "from" : "gu",
          "desc" : "皮膚黑站粟、武器長黍图、性格直",
          "tags" : [
            "黑",
            "長",
            "直"
          ]
        },
        "highlight" : {
          "name" : [
            "<em>顧</em><em>老</em><em>二</em>"
          ]
        }
      }
    ]
  }
}
ES自定義高亮顯示(在highlight中,pre_tags用來實(shí)現(xiàn)我們的自定義標(biāo)簽的前半部分奴烙,在這里助被,我們也可以為自定義的 標(biāo)簽添加屬性和樣式。post_tags實(shí)現(xiàn)標(biāo)簽的后半部分切诀,組成一個完整的標(biāo)簽揩环。至于標(biāo)簽中的內(nèi)容,則還是交給fields來完成)
GET test3/doc/_search
{
  "query": {
    "match": {
      "desc": "性格直"
    }
  },
  "highlight": {
    "pre_tags": "<b class='key' style='color:red'>",
    "post_tags": "</b>",
    "fields": {
      "desc": {}
    }
  }
}

>>查詢結(jié)果
{
  "took" : 6,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.8630463,
    "hits" : [
      {
        "_index" : "test3",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.8630463,
        "_source" : {
          "name" : "顧老二",
          "age" : 30,
          "from" : "gu",
          "desc" : "皮膚黑幅虑、武器長丰滑、性格直",
          "tags" : [
            "黑",
            "長",
            "直"
          ]
        },
        "highlight" : {
          "desc" : [
            "皮膚黑、武器長倒庵、<b class='key' style='color:red'>性</b><b class='key' style='color:red'>格</b><b class='key' style='color:red'>直</b>"
          ]
        }
      }
    ]
  }
}

十褒墨、ES之精確查詢與模糊查詢

  • term查詢查找包含文檔精確的倒排索引指定的詞條。也就是精確查找擎宝。
term和match的區(qū)別是:match是經(jīng)過analyer的郁妈,也就是說,文檔首先被分析器給處理了绍申。根據(jù)不同的分析器噩咪,分析的結(jié)果也稍顯不同锄奢,然后再根據(jù)分詞結(jié)果進(jìn)行匹配。term則不經(jīng)過分詞剧腻,它是直接去倒排索引中查找了精確的值了拘央。
#### 準(zhǔn)備數(shù)據(jù)
PUT w1
{
  "mappings": {
    "doc": {
      "properties":{
        "t1":{
          "type": "text"
        },
        "t2": {
          "type": "keyword"
        }
      }
    }
  }
}

PUT w1/doc/1
{
  "t1": "hi single dog",
  "t2": "hi single dog"
}
  • 對比兩者的不同 (結(jié)果就不展示出來了,只展示結(jié)果的文字?jǐn)⑹?
# t1類型為text书在,會經(jīng)過分詞灰伟,match查詢時條件也會經(jīng)過分詞,所以下面兩種查詢都能查到結(jié)果
GET w1/doc/_search
{
  "query": {
    "match": {
      "t1": "hi single dog" 
    }
  }
}

GET w1/doc/_search
{
  "query": {
    "match": {
      "t1": "hi" 
    }
  }
}

# t2類型為keyword類型儒旬,不會經(jīng)過分詞栏账,match查詢時條件會經(jīng)過分詞,所以只能當(dāng)值為"hi single dog"時能查詢到
GET w1/doc/_search
{
  "query": {
    "match": {
      "t2": "hi" 
    }
  }
}

GET w1/doc/_search
{
  "query": {
    "match": {
      "t2": "hi single dog" 
    }
  }
}

# t1類型為text栈源,會經(jīng)過分詞挡爵,term查詢時條件不會經(jīng)過分詞,所以只有當(dāng)值為"hi"時能查詢到
GET w1/doc/_search
{
  "query": {
    "term": {
      "t1": "hi single dog" 
    }
  }
}

GET w1/doc/_search
{
  "query": {
    "term": {
      "t1": "hi" 
    }
  }
}

# t2類型為keyword類型甚垦,不會經(jīng)過分詞茶鹃,term查詢時條件不會經(jīng)過分詞,所以只能當(dāng)值為"hi single dog"時能查詢到

GET w1/doc/_search
{
  "query": {
    "term": {
      "t2": "hi single dog" 
    }
  }
}

GET w1/doc/_search
{
  "query": {
    "term": {
      "t2": "hi" 
    }
  }
}
  • 查找多個精確值(terms)
#### 第一個查詢方式
GET test/doc/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "age":27
          }
        },{
          "term":{
            "age":28
          }
        }
      ]
    }
  }
}


# 第二個查詢方式
GET test/doc/_search
{
  "query": {
    "terms": {
      "age": [
        "27",
        "28"
      ]
    }
  }
}

>>>兩種方式的查詢結(jié)果都是一下結(jié)果 
{
  "took" : 10,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "test",
        "_type" : "doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "name" : "wangfei",
          "age" : 27,
          "desc" : "熱天還不讓后人不認(rèn)同"
        }
      },
      {
        "_index" : "test",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "wangjifei",
          "age" : 27,
          "desc" : "生活就像 茫茫海上"
        }
      }
    ]
  }
}

十一艰亮、ES的聚合查詢avg闭翩、max、min迄埃、sum

####  數(shù)據(jù)準(zhǔn)備

PUT zhifou/doc/1
{
  "name":"顧老二",
  "age":30,
  "from": "gu",
  "desc": "皮膚黑疗韵、武器長、性格直",
  "tags": ["黑", "長", "直"]
}

PUT zhifou/doc/2
{
  "name":"大娘子",
  "age":18,
  "from":"sheng",
  "desc":"膚白貌美侄非,嬌憨可愛",
  "tags":["白", "富","美"]
}

PUT zhifou/doc/3
{
  "name":"龍?zhí)灼?,
  "age":22,
  "from":"gu",
  "desc":"mmp蕉汪,沒怎么看,不知道怎么形容",
  "tags":["造數(shù)據(jù)", "真","難"]
}


PUT zhifou/doc/4
{
  "name":"石頭",
  "age":29,
  "from":"gu",
  "desc":"粗中有細(xì)逞怨,狐假虎威",
  "tags":["粗", "大","猛"]
}

PUT zhifou/doc/5
{
  "name":"魏行首",
  "age":25,
  "from":"廣云臺",
  "desc":"仿佛兮若輕云之蔽月,飄飄兮若流風(fēng)之回雪,mmp者疤,最后竟然沒有嫁給顧老二!",
  "tags":["閉月","羞花"]
}

GET zhifou/doc/_search
{
  "query": {
    "match_all": {}
  }
}
  • 需求1骇钦、查詢from是gu的人的平均年齡宛渐。
GET zhifou/doc/_search
{
  "query": {
    "match": {
      "from": "gu"
    }
  },
  "aggs": {
    "my_avg": {
      "avg": {
        "field": "age"
      }
    }
  },
  "_source": ["name", "age"]
}

>>>查詢結(jié)果
{
  "took" : 83,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 3,
    "max_score" : 0.6931472,
    "hits" : [
      {
        "_index" : "zhifou",
        "_type" : "doc",
        "_id" : "4",
        "_score" : 0.6931472,
        "_source" : {
          "name" : "石頭",
          "age" : 29
        }
      },
      {
        "_index" : "zhifou",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "name" : "顧老二",
          "age" : 30
        }
      },
      {
        "_index" : "zhifou",
        "_type" : "doc",
        "_id" : "3",
        "_score" : 0.2876821,
        "_source" : {
          "name" : "龍?zhí)灼?,
          "age" : 22
        }
      }
    ]
  },
  "aggregations" : {
    "my_avg" : {
      "value" : 27.0
    }
  }
}
上例中,首先匹配查詢from是gu的數(shù)據(jù)眯搭。在此基礎(chǔ)上做查詢平均值的操作窥翩,這里就用到了聚合函數(shù),其語法被封裝在aggs中鳞仙,而my_avg則是為查詢結(jié)果起個別名寇蚊,封裝了計(jì)算出的平均值。那么棍好,要以什么屬性作為條件呢仗岸?是age年齡允耿,查年齡的什么呢?是avg扒怖,查平均年齡较锡。
如果只想看輸出的值,而不關(guān)心輸出的文檔的話可以通過size=0來控制
GET zhifou/doc/_search
{
  "query": {
    "match": {
      "from": "gu"
      }
    },
    "aggs":{
      "my_avg":{
        "avg": {
          "field": "age"
        }
      }
    },
    "size":0,
    "_source":["name","age"]
}

>>>查詢結(jié)果
{
  "took" : 35,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 3,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "my_avg" : {
      "value" : 27.0
    }
  }
}
  • 需求2盗痒、查詢年齡的最大值
GET zhifou/doc/_search
{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "my_max": {
      "max": {
        "field": "age"
      }
    }
  },
  "size": 0, 
  "_source": ["name","age","from"]
}

>>>查詢結(jié)果
{
  "took" : 10,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 5,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "my_max" : {
      "value" : 30.0
    }
  }
}
  • 需求3蚂蕴、查詢年齡的最小值
GET zhifou/doc/_search
{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "my_min": {
      "min": {
        "field": "age"
      }
    }
  },
  "size": 0, 
  "_source": ["name","age","from"]
}

>>>查詢結(jié)果
{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 5,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "my_min" : {
      "value" : 18.0
    }
  }
}
  • 需求4、查詢符合條件的年齡之和
GET zhifou/doc/_search
{
  "query": {
    "match": {
      "from": "gu"
    }
  },
    "aggs": {
    "my_sum": {
      "sum": {
        "field": "age"
      }
    }
  },
  "size": 0, 
  "_source": ["name","age","from"]
}

>>>查詢結(jié)果
{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 3,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "my_sum" : {
      "value" : 81.0
    }
  }
}

十二俯邓、ES的分組查詢

  • 需求: 要查詢所有人的年齡段骡楼,并且按照1520,2025,25~30分組稽鞭,并且算出每組的平均年齡鸟整。
GET zhifou/doc/_search
{
  "size": 0, 
  "query": {
    "match_all": {}
  },
  "aggs": {
    "age_group": {
      "range": {
        "field": "age",
        "ranges": [
          {
            "from": 15,
            "to": 20
          },
          {
            "from": 20,
            "to": 25
          },
          {
            "from": 25,
            "to": 30
          }
        ]
      }
    }
  }
}

>>>查詢結(jié)果
{
  "took" : 9,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 5,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "age_group" : {
      "buckets" : [
        {
          "key" : "15.0-20.0",
          "from" : 15.0,
          "to" : 20.0,
          "doc_count" : 1
        },
        {
          "key" : "20.0-25.0",
          "from" : 20.0,
          "to" : 25.0,
          "doc_count" : 1
        },
        {
          "key" : "25.0-30.0",
          "from" : 25.0,
          "to" : 30.0,
          "doc_count" : 2
        }
      ]
    }
  }
}
上例中,在aggs的自定義別名age_group中朦蕴,使用range來做分組篮条,field是以age為分組,分組使用ranges來做梦重,from和to是范圍
  • 接下來兑燥,我們就要對每個小組內(nèi)的數(shù)據(jù)做平均年齡處理。
GET zhifou/doc/_search
{
  "size": 0, 
  "query": {
    "match_all": {}
  },
  "aggs": {
    "age_group": {
      "range": {
        "field": "age",
        "ranges": [
          {
            "from": 15,
            "to": 20
          },
          {
            "from": 20,
            "to": 25
          },
          {
            "from": 25,
            "to": 30
          }
        ]
      },
      "aggs": {
        "my_avg": {
          "avg": {
            "field": "age"
          }
        }
      }
    }
  }
}

>>>查詢結(jié)果
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 5,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "age_group" : {
      "buckets" : [
        {
          "key" : "15.0-20.0",
          "from" : 15.0,
          "to" : 20.0,
          "doc_count" : 1,
          "my_avg" : {
            "value" : 18.0
          }
        },
        {
          "key" : "20.0-25.0",
          "from" : 20.0,
          "to" : 25.0,
          "doc_count" : 1,
          "my_avg" : {
            "value" : 22.0
          }
        },
        {
          "key" : "25.0-30.0",
          "from" : 25.0,
          "to" : 30.0,
          "doc_count" : 2,
          "my_avg" : {
            "value" : 27.0
          }
        }
      ]
    }
  }
}

ES的聚合查詢的總結(jié):聚合函數(shù)的使用琴拧,一定是先查出結(jié)果,然后對結(jié)果使用聚合函數(shù)做處理

avg:求平均

max:最大值

min:最小值

sum:求和

十三嘱支、ES之Mappings

GET test

>>>查詢結(jié)果
{
  "test" : {
    "aliases" : { },
    "mappings" : {
      "doc" : {
        "properties" : {
          "age" : {
            "type" : "long"
          },
          "desc" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
            }
          },
          "name" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
            }
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "creation_date" : "1569133097594",
        "number_of_shards" : "5",
        "number_of_replicas" : "1",
        "uuid" : "AztO9waYQiyHvzP6dlk4tA",
        "version" : {
          "created" : "6080299"
        },
        "provided_name" : "test"
      }
    }
  }
}

由返回結(jié)果可以看到蚓胸,分為兩大部分:
第一部分關(guān)于t1索引類型相關(guān)的,包括該索引是否有別名aliases除师,然后就是mappings信息沛膳,
包括索引類型doc,各字段的詳細(xì)映射關(guān)系都收集在properties中汛聚。

另一部分是關(guān)于索引t1的settings設(shè)置锹安。包括該索引的創(chuàng)建時間,主副分片的信息倚舀,UUID等等叹哭。

1. mappings 是什么?

映射就是在創(chuàng)建索引的時候痕貌,有更多定制的內(nèi)容风罩,更加的貼合業(yè)務(wù)場景。
用來定義一個文檔及其包含的字段如何存儲和索引的過程舵稠。

2. 字段的數(shù)據(jù)類型

簡單類型如文本(text)超升、關(guān)鍵字(keyword)入宦、日期(data)、整形(long)室琢、雙精度
(double)乾闰、布爾(boolean)或ip。 可以是支持JSON的層次結(jié)構(gòu)性質(zhì)的類型盈滴,如對象或嵌套涯肩。
或者一種特殊類型,如geo_point雹熬、geo_shape或completion宽菜。為了不同的目的,
以不同的方式索引相同的字段通常是有用的竿报。例如铅乡,字符串字段可以作為全文搜索的文本字段進(jìn)行索引,
也可以作為排序或聚合的關(guān)鍵字字段進(jìn)行索引烈菌≌笮遥或者,可以使用標(biāo)準(zhǔn)分析器芽世、英語分析器和
法語分析器索引字符串字段挚赊。這就是多字段的目的。大多數(shù)數(shù)據(jù)類型通過fields參數(shù)支持多字段济瓢。
  • 一個簡單的映射示例
PUT mapping_test
{
  "mappings": {
    "test1":{
      "properties":{
        "name":{"type": "text"},
        "age":{"type":"long"}
      }
    }
  }
}
我們在創(chuàng)建索引PUT mapping_test1的過程中荠割,為該索引定制化類型(設(shè)計(jì)表結(jié)構(gòu)),添加一個映射類型test1旺矾;指定字段或者屬性都在properties內(nèi)完成蔑鹦。
GET mapping_test

>>>查詢結(jié)果
{
  "mapping_test" : {
    "aliases" : { },
    "mappings" : {
      "test1" : {
        "properties" : {
          "age" : {
            "type" : "long"
          },
          "name" : {
            "type" : "text"
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "creation_date" : "1570794586526",
        "number_of_shards" : "5",
        "number_of_replicas" : "1",
        "uuid" : "P4-trriPTxq-nJj89iYXZA",
        "version" : {
          "created" : "6080299"
        },
        "provided_name" : "mapping_test"
      }
    }
  }
}
返回的結(jié)果中你肯定很熟悉!映射類型是test1箕宙,具體的屬性都被封裝在properties中嚎朽。

3. ES mappings之dynamic的三種狀態(tài)

  • 一般的,mapping則又可以分為動態(tài)映射(dynamic mapping)和靜態(tài)(顯示)映射(explicit mapping)和精確(嚴(yán)格)映射(strict mappings)柬帕,具體由dynamic屬性控制哟忍。默認(rèn)為動態(tài)映射
##### 默認(rèn)為動態(tài)映射
PUT test4
{
  "mappings": {
    "doc":{
      "properties": {
        "name": {
          "type": "text"
        },
        "age": {
          "type": "long"
        }
      }
    }
  }
}

GET test4/_mapping
>>>查詢結(jié)果
{
  "test4" : {
    "mappings" : {
      "doc" : {
        "properties" : {
          "age" : {
            "type" : "long"
          },
          "name" : {
            "type" : "text"
          },
          "sex" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
            }
          }
        }
      }
    }
  }
}

#####添加數(shù)據(jù)
PUT test4/doc/1
{
  "name":"wangjifei",
  "age":"18",
  "sex":"不詳"
}

#####查看數(shù)據(jù)
GET test4/doc/_search
{
  "query": {
    "match_all": {}
  }
}

>>>查詢結(jié)果
{
  "took" : 8,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "test4",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "wangjifei",
          "age" : "18",
          "sex" : "不詳"
        }
      }
    ]
  }
}
  • 測試靜態(tài)映射:當(dāng)elasticsearch察覺到有新增字段時,因?yàn)閐ynamic:false的關(guān)系陷寝,會忽略該字段锅很,但是仍會存儲該字段。
#####創(chuàng)建靜態(tài)mapping
PUT test5
{
  "mappings": {
    "doc":{
      "dynamic":false,
      "properties": {
        "name": {
          "type": "text"
        },
        "age": {
          "type": "long"
        }
      }
    }
  }
}

#####插入數(shù)據(jù)
PUT test5/doc/1
{
  "name":"wangjifei",
  "age":"18",
  "sex":"不詳"
}

####條件查詢
GET test5/doc/_search
{
  "query": {
    "match": {
      "sex": "不詳"
    }
  }
}

>>>查詢結(jié)果
{
  "took" : 9,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 0,
    "max_score" : null,
    "hits" : [ ]
  }
}

#####查看所有數(shù)據(jù)
GET /test5/doc/_search
{
  "query": {
    "match_all": {}
  }
}

>>>查詢結(jié)果
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "test5",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "wangjifei",
          "age" : "18",
          "sex" : "不詳"
        }
      }
    ]
  }
}

  • 測試嚴(yán)格映射:當(dāng)elasticsearch察覺到有新增字段時盼铁,因?yàn)閐ynamic:strict 的關(guān)系粗蔚,就會報(bào)錯,不能插入成功饶火。
#####創(chuàng)建嚴(yán)格mapping
PUT test6
{
  "mappings": {
    "doc":{
      "dynamic":"strict",
      "properties": {
        "name": {
          "type": "text"
        },
        "age": {
          "type": "long"
        }
      }
    }
  }
}

#####插入數(shù)據(jù)
PUT test6/doc/1
{
  "name":"wangjifei",
  "age":"18",
  "sex":"不詳"
}

>>>插入結(jié)果
{
  "error": {
    "root_cause": [
      {
        "type": "strict_dynamic_mapping_exception",
        "reason": "mapping set to strict, dynamic introduction of [sex] within [doc] is not allowed"
      }
    ],
    "type": "strict_dynamic_mapping_exception",
    "reason": "mapping set to strict, dynamic introduction of [sex] within [doc] is not allowed"
  },
  "status": 400
}

小結(jié): 動態(tài)映射(dynamic:true):動態(tài)添加新的字段(或缺逝艨亍)致扯。 靜態(tài)映射(dynamic:false):忽略新的字段。在原有的映射基礎(chǔ)上当辐,當(dāng)有新的字段時抖僵,不會主動的添加新的映射關(guān)系,只作為查詢結(jié)果出現(xiàn)在查詢中缘揪。 嚴(yán)格模式(dynamic:strict):如果遇到新的字段耍群,就拋出異常。一般靜態(tài)映射用的較多找筝。就像HTML的img標(biāo)簽一樣蹈垢,src為自帶的屬性,你可以在需要的時候添加id或者class屬性袖裕。當(dāng)然曹抬,如果你非常非常了解你的數(shù)據(jù),并且未來很長一段時間不會改變急鳄,strict不失為一個好選擇谤民。

4. ES之mappings的 index 屬性

  • index屬性默認(rèn)為true,如果該屬性設(shè)置為false疾宏,那么张足,elasticsearch不會為該屬性創(chuàng)建索引,也就是說無法當(dāng)做主查詢條件坎藐。
PUT test7
{
  "mappings": {
    "doc": {
      "properties": {
        "name": {
          "type": "text",
          "index": true
        },
        "age": {
          "type": "long",
          "index": false
        }
      }
    }
  }
}

####插入數(shù)據(jù)
PUT test7/doc/1
{
  "name":"wangjifei",
  "age":18
}

####條件查詢數(shù)據(jù)
GET test7/doc/_search
{
  "query": {
    "match": {
      "name": "wangjifei"
    }
  }
}

>>>查詢結(jié)果
{
  "took" : 18,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "test7",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "name" : "wangjifei",
          "age" : 18
        }
      }
    ]
  }
}

#####條件查詢
GET test7/doc/_search
{
  "query": {
    "match": {
      "age": 18
    }
  }
}

>>>查詢結(jié)果
{
  "error": {
    "root_cause": [
      {
        "type": "query_shard_exception",
        "reason": "failed to create query: {\n  \"match\" : {\n    \"age\" : {\n      \"query\" : 18,\n      \"operator\" : \"OR\",\n      \"prefix_length\" : 0,\n      \"max_expansions\" : 50,\n      \"fuzzy_transpositions\" : true,\n      \"lenient\" : false,\n      \"zero_terms_query\" : \"NONE\",\n      \"auto_generate_synonyms_phrase_query\" : true,\n      \"boost\" : 1.0\n    }\n  }\n}",
        "index_uuid": "fzN9frSZRy2OzinRjeMKGA",
        "index": "test7"
      }
    ],
    "type": "search_phase_execution_exception",
    "reason": "all shards failed",
    "phase": "query",
    "grouped": true,
    "failed_shards": [
      {
        "shard": 0,
        "index": "test7",
        "node": "INueKtviRpO1dbNWngcjJA",
        "reason": {
          "type": "query_shard_exception",
          "reason": "failed to create query: {\n  \"match\" : {\n    \"age\" : {\n      \"query\" : 18,\n      \"operator\" : \"OR\",\n      \"prefix_length\" : 0,\n      \"max_expansions\" : 50,\n      \"fuzzy_transpositions\" : true,\n      \"lenient\" : false,\n      \"zero_terms_query\" : \"NONE\",\n      \"auto_generate_synonyms_phrase_query\" : true,\n      \"boost\" : 1.0\n    }\n  }\n}",
          "index_uuid": "fzN9frSZRy2OzinRjeMKGA",
          "index": "test7",
          "caused_by": {
            "type": "illegal_argument_exception",
            "reason": "Cannot search on field [age] since it is not indexed."
          }
        }
      }
    ]
  },
  "status": 400
}

5. ES 之 mappings 的copy_to屬性

PUT test8
{
  "mappings": {
    "doc": {
      "dynamic":false,
      "properties": {
        "first_name":{
          "type": "text",
          "copy_to": "full_name"
        },
        "last_name": {
          "type": "text",
          "copy_to": "full_name"
        },
        "full_name": {
          "type": "text"
        }
      }
    }
  }
}

#####插入數(shù)據(jù)
PUT test8/doc/1
{
  "first_name":"tom",
  "last_name":"ben"
}
PUT test8/doc/2
{
  "first_name":"john",
  "last_name":"smith"
}

#####查詢所有
GET test8/doc/_search
{
  "query": {
    "match_all": {}
  }
}

>>>查詢結(jié)果
{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "test8",
        "_type" : "doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "first_name" : "john",
          "last_name" : "smith"
        }
      },
      {
        "_index" : "test8",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "first_name" : "tom",
          "last_name" : "ben"
        }
      }
    ]
  }
}

#####條件查詢
GET test8/doc/_search
{
  "query": {
    "match": {
      "first_name": "tom"
    }
  }
}

>>>查詢結(jié)果
{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "test8",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "first_name" : "tom",
          "last_name" : "ben"
        }
      }
    ]
  }
}

######條件查詢
GET test8/doc/_search
{
  "query": {
    "match": {
      "full_name": "ben"
    }
  }
}

>>>查詢結(jié)果
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "test8",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "first_name" : "tom",
          "last_name" : "ben"
        }
      }
    ]
  }
}
上例中为牍,我們將first_name和last_name都復(fù)制到full_name中。并且使用full_name查詢也返回了結(jié)果
  • 既要查詢tom還要查詢smith該怎么辦岩馍?
GET test8/doc/_search
{
  "query": {
    "match": {
      "full_name": {
        "query": "tom smith",
        "operator": "or"
      }
    }
  }
}

>>>查詢結(jié)果
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "test8",
        "_type" : "doc",
        "_id" : "2",
        "_score" : 0.2876821,
        "_source" : {
          "first_name" : "john",
          "last_name" : "smith"
        }
      },
      {
        "_index" : "test8",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "first_name" : "tom",
          "last_name" : "ben"
        }
      }
    ]
  }
}
operator參數(shù)為多個條件的查詢關(guān)系也可以是and
  • 上面的查詢還可以簡寫成一下:
GET test8/doc/_search
{
  "query": {
    "match": {
      "full_name": "tom smith"
    }
  }
}
  • copy_to還支持將相同的屬性值復(fù)制給不同的字段吵聪。
PUT test9
{
  "mappings": {
    "doc": {
      "dynamic":false,
      "properties": {
        "first_name":{
          "type": "text",
          "copy_to": ["full_name1","full_name2"]
        },
        "last_name": {
          "type": "text",
          "copy_to": ["full_name1","full_name2"]
        },
        "full_name1": {
          "type": "text"
        },
        "full_name2":{
          "type":"text"
        }
      }
    }
  }
}

####插入數(shù)據(jù)
PUT test9/doc/1
{
  "first_name":"tom",
  "last_name":"ben"
}

PUT test9/doc/2
{
  "first_name":"john",
  "last_name":"smith"
}

####條件查詢
GET test9/doc/_search
{
  "query": {
    "match": {
      "full_name1": "tom smith"
    }
  }
}

>>>查詢結(jié)果
{
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "test9",
        "_type" : "doc",
        "_id" : "2",
        "_score" : 0.2876821,
        "_source" : {
          "first_name" : "john",
          "last_name" : "smith"
        }
      },
      {
        "_index" : "test9",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "first_name" : "tom",
          "last_name" : "ben"
        }
      }
    ]
  }
}

#####條件查詢
GET test9/doc/_search
{
  "query": {
    "match": {
      "full_name2": "tom smith"
    }
  }
}

>>>查詢結(jié)果
{
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "test9",
        "_type" : "doc",
        "_id" : "2",
        "_score" : 0.2876821,
        "_source" : {
          "first_name" : "john",
          "last_name" : "smith"
        }
      },
      {
        "_index" : "test9",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "first_name" : "tom",
          "last_name" : "ben"
        }
      }
    ]
  }
}
full_name1 full_name2兩個字段都可以查出來

6. ES 之mappings的對象屬性

  • 首先先看看ES自動創(chuàng)建的mappings
PUT test10/doc/1
{
  "name":"wangjifei",
  "age":18,
  "info":{
    "addr":"北京",
    "tel":"18500327026"
  }
}

GET test10

>>>查詢結(jié)果
{
  "test10" : {
    "aliases" : { },
    "mappings" : {
      "doc" : {
        "properties" : {
          "age" : {
            "type" : "long"
          },
          "info" : {
            "properties" : {
              "addr" : {
                "type" : "text",
                "fields" : {
                  "keyword" : {
                    "type" : "keyword",
                    "ignore_above" : 256
                  }
                }
              },
              "tel" : {
                "type" : "text",
                "fields" : {
                  "keyword" : {
                    "type" : "keyword",
                    "ignore_above" : 256
                  }
                }
              }
            }
          },
          "name" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
            }
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "creation_date" : "1570975011394",
        "number_of_shards" : "5",
        "number_of_replicas" : "1",
        "uuid" : "YvMGDHxkSri0Lgx6GGXiNw",
        "version" : {
          "created" : "6080299"
        },
        "provided_name" : "test10"
      }
    }
  }
}
  • 現(xiàn)在如果要以info中的tel為條件怎么寫查詢語句呢?
GET test10/doc/_search
{
  "query": {
    "match": {
      "info.tel": "18500327026"
    }
  }
}

>>>查詢結(jié)果
{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "test10",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "name" : "wangjifei",
          "age" : 18,
          "info" : {
            "addr" : "北京",
            "tel" : "18500327026"
          }
        }
      }
    ]
  }
}
info既是一個屬性兼雄,也是一個對象,我們稱為info這類字段為對象型字段帽蝶。該對象內(nèi)又包含addr和tel兩個字段赦肋,如上例這種以嵌套內(nèi)的字段為查詢條件的話,查詢語句可以以字段點(diǎn)子字段的方式來寫即可

7. ES之mappings的settings 設(shè)置

  • 在創(chuàng)建一個索引的時候励稳,我們可以在settings中指定分片信息:
PUT test11
{
  "mappings": {
    "doc": {
      "properties": {
        "name": {
          "type": "text"
        }
      }
    }
  }, 
  "settings": {
    "number_of_replicas": 1,
    "number_of_shards": 5
  }
}
number_of_shards是主分片數(shù)量(每個索引默認(rèn)5個主分片)佃乘,而number_of_replicas是復(fù)制分片,默認(rèn)一個主分片搭配一個復(fù)制分片驹尼。

8. ES 之mappings的ignore_above參數(shù)

  • ignore_above參數(shù)僅針對于keyword類型有用
# 這樣設(shè)置是會報(bào)錯的
PUT test12
{
  "mappings": {
    "doc": {
      "properties": {
        "name": {
          "type": "text",
          "ignore_above":5
        }
      }
    }
  }
}

>>>顯示結(jié)果
{
  "error": {
    "root_cause": [
      {
        "type": "mapper_parsing_exception",
        "reason": "Mapping definition for [name] has unsupported parameters:  [ignore_above : 5]"
      }
    ],
    "type": "mapper_parsing_exception",
    "reason": "Failed to parse mapping [doc]: Mapping definition for [name] has unsupported parameters:  [ignore_above : 5]",
    "caused_by": {
      "type": "mapper_parsing_exception",
      "reason": "Mapping definition for [name] has unsupported parameters:  [ignore_above : 5]"
    }
  },
  "status": 400
}
##### 正確的打開方式
PUT test12
{
  "mappings": {
    "doc": {
      "properties": {
        "name": {
          "type": "keyword",
          "ignore_above":5
        }
      }
    }
  }
}

PUT test12/doc/1
{
  "name":"wangjifei"
}

##### 這樣查詢能查出結(jié)果
GET test12/doc/_search
{
  "query": {
    "match_all": {}
  }
}

>>>查詢結(jié)果
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "test12",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "wangjifei"
        }
      }
    ]
  }
}


######這樣查詢不能查詢出結(jié)果
GET test12/doc/_search
{
  "query": {
    "match": {
      "name": "wangjifei"
    }
  }
}

>>>查詢結(jié)果
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 0,
    "max_score" : null,
    "hits" : [ ]
  }
}
上面的例子證明超過ignore_above設(shè)定的值后會被存儲但不會建立索引
  • 那么如果字符串的類型是text時能用ignore_above嗎趣避,答案是能,但要特殊設(shè)置:
PUT test13
{
  "mappings": {
    "doc":{
      "properties":{
        "name1":{
          "type":"keyword",
          "ignore_above":5
        },
        "name2":{
          "type":"text",
          "fields":{
            "keyword":{
              "type":"keyword",
              "ignore_above": 10
            }
          }
        }
      }
    }
  }
}

PUT test13/doc/1
{
  "name1":"wangfei",
  "name2":"wangjifei hello"
}

##### 能查出來
GET test13/doc/_search
{
  "query": {
    "match_all": {}
  }
}

>>>查詢結(jié)果
{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "test13",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name1" : "wangfei",
          "name2" : "wangjifei hello"
        }
      }
    ]
  }
}

##### 通過name1 字段查不出來新翎,因?yàn)樵O(shè)置的是keyword類型 限制了5個字符的長度程帕,
##### 存儲的值超過了最大限制
GET test13/doc/_search
{
  "query": {
    "match": {
      "name1": "wangfei"
    }
  }
}

>>>查詢結(jié)果
{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 0,
    "max_score" : null,
    "hits" : [ ]
  }
}

##### 通過name2 字段能查出來住练,雖然限制了5個字符的長度,存儲的值超過了最大限制愁拭,但是讲逛,
##### 當(dāng)字段類型設(shè)置為text之后,ignore_above參數(shù)的限制就失效了岭埠。(了解就好盏混,意義不大)
GET test13/doc/_search
{
  "query": {
    "match": {
      "name2": "wangjifei"
    }
  }
}

>>>查詢結(jié)果
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "test13",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "name1" : "wangfei",
          "name2" : "wangjifei hello"
        }
      }
    ]
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市惜论,隨后出現(xiàn)的幾起案子许赃,更是在濱河造成了極大的恐慌,老刑警劉巖馆类,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件混聊,死亡現(xiàn)場離奇詭異,居然都是意外死亡蹦掐,警方通過查閱死者的電腦和手機(jī)技羔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來卧抗,“玉大人藤滥,你說我怎么就攤上這事∩珩桑” “怎么了拙绊?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長泳秀。 經(jīng)常有香客問我标沪,道長,這世上最難降的妖魔是什么嗜傅? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任金句,我火速辦了婚禮,結(jié)果婚禮上吕嘀,老公的妹妹穿的比我還像新娘违寞。我一直安慰自己,他們只是感情好偶房,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布趁曼。 她就那樣靜靜地躺著,像睡著了一般棕洋。 火紅的嫁衣襯著肌膚如雪挡闰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天,我揣著相機(jī)與錄音摄悯,去河邊找鬼赞季。 笑死,一個胖子當(dāng)著我的面吹牛射众,可吹牛的內(nèi)容都是我干的碟摆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼叨橱,長吁一口氣:“原來是場噩夢啊……” “哼典蜕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起罗洗,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤愉舔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后伙菜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體轩缤,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年贩绕,在試婚紗的時候發(fā)現(xiàn)自己被綠了火的。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片化借。...
    茶點(diǎn)故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡递鹉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出款侵,到底是詐尸還是另有隱情娇哆,我是刑警寧澤湃累,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站碍讨,受9級特大地震影響治力,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜勃黍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一宵统、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧覆获,春花似錦榜田、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽净捅。三九已至疑枯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蛔六,已是汗流浹背荆永。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工废亭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人具钥。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓豆村,卻偏偏與公主長得像,于是被迫代替她去往敵國和親骂删。 傳聞我的和親對象是個殘疾皇子掌动,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容