├── README.md ├── base.md ├── data ├── book_document.json ├── book_mapping.json └── comparison.png ├── indexing_data.md ├── restful_api.md └── searching_data.md /README.md: -------------------------------------------------------------------------------- 1 | Elasticsearch学习笔记。 2 | 3 | 主要参考Elasticsearch Server这本书,同时会包含Mastering Elasticsearch相关内容。 4 | 5 | ## Table of Contents 6 | 7 | 1. [Base](./base.md) 8 | 2. [Restful API](./restful_api.md) 9 | 3. [Indexing Data](./indexing_data.md) 10 | 4. [Searching Data](./searching_data.md) -------------------------------------------------------------------------------- /base.md: -------------------------------------------------------------------------------- 1 | ## Lucene 2 | 3 | Elasticsearch使用Lucene作为其底层的搜索引擎,关于Lucene的介绍,可以参考[官方网站](http://lucene.apache.org)。 4 | 5 | Lucene关键概念: 6 | 7 | + Document:用来索引和搜索的主要数据源,包含一个或者多个Field,而这些Field则包含我们跟Lucene交互的数据。 8 | + Field:Document的一个组成部分,有两个部分组成,name和value。 9 | + Term:不可分割的词语,搜索里面最小单元。 10 | + Token:一个Term呈现方式,包含这个Term的文字,在文档中的起始位置,以及类型。 11 | 12 | Lucene使用[Inverted index](http://en.wikipedia.org/wiki/Inverted_index)来存储term在document中位置的映射关系。 13 | 譬如如下文档: 14 | 15 | - Elasticsearch Server 1.0 (document 1) 16 | - Mastring Elasticsearch (document 2) 17 | - Apache Solr 4 Cookbook (document 3) 18 | 19 | 使用inverted index存储,一个简单地映射关系: 20 | 21 | |Term|Count|Docuemnt| 22 | |----|-----|--------| 23 | |1.0|1|\<1\>| 24 | |4|1|\<3\>| 25 | |Apache|1|\<3\>| 26 | |Cookbook|1|\<3\>| 27 | |Elasticsearch|2|\<1\>.\<2\>| 28 | |Mastering|1|\<2\>| 29 | |Server|1|\<1\>| 30 | |Solr|1|\<3\>| 31 | 32 | 在上面的例子中,我们首先将文档切分成一个一个term,也就是用空格分割,然后映射表里面记录该term总的出现次数以及在哪个document里面。 33 | 34 | ## Input data analysis 35 | 36 | Document里面的数据如何生成inverted index?查询语句如何切分成terms并允许搜索?相关的东西我们叫做analysis。 37 | 38 | Analysis通过analyzer实现,主要包括tokenizer,token filters以及character mappers。 39 | 40 | + Tokenizer:也就是通常说的词法分析,将一个文本切分成tokens。词法分析结束之后,结果我们叫做token stream。 41 | + Token filter:用来在token stream里面处理token,filter是依次运行的。一些filter例子: 42 | + Lowercase filter 43 | + Synonyms filter 44 | + Multiple language stemming filters 45 | + Character mappers: 用于处理不可直接解析的文本,在tokenizer之前使用,譬如对于一个html文件移除相关html的tag。 46 | 47 | ## Scoring and query relevance 48 | 49 | Score: 用来表示一个document跟查询语句的匹配程度,score越高,表明越匹配。 50 | 51 | Lucene使用[**TF/IDF**](http://en.wikipedia.org/wiki/Tf–idf)这套计算得分算法。 52 | 53 | ## Elasticsearch基本概念 54 | 55 | Data: 56 | 57 | + Index:Elasticsearch用来存储数据的逻辑区域,它类似于关系型数据库中的database 概念。一个index可以在一个或者多个shard上面,同时一个shard也可能会有多个replicas。 58 | + Document:Elasticsearch里面存储的实体数据,类似于关系数据中一个table里面的一行数据。 59 | document由多个field组成,不同的document里面同名的field一定具有相同的类型。document里面field可以重复出现,也就是一个field会有多个值,即multivalued。 60 | + Document type:为了查询需要,一个index可能会有多种document,也就是document type. 它类似于关系型数据库中的 table 概念。但需要注意,不同document里面同名的field一定要是相同类型的。 61 | + Mapping:它类似于关系型数据库中的 schema 定义概念。存储field的相关映射信息,不同document type会有不同的mapping。 62 | 63 | 下图是 ElasticSearch 和 关系型数据库的一些术语比较。 64 | 65 | ![](./data/comparison.png) 66 | 67 | Server: 68 | 69 | + Node: 一个server实例 70 | + Cluster:多个node组成cluster 71 | + Shard:数据分片,一个index可能会有多个shards,不同shards可能在不同nodes 72 | + Replica:shard的备份,有一个primary shard,其余的叫做replica shards 73 | + Gateway:管理cluster状态信息 74 | 75 | 76 | -------------------------------------------------------------------------------- /data/book_document.json: -------------------------------------------------------------------------------- 1 | {"index": {"_index": "library", "_type": "book", "_id": "1"}} 2 | {"title": "All Quiet on the Western Front","otitle": "Im Westen nichts Neues","author": "Erich Maria Remarque","year": 1929,"characters": ["Paul Bäumer", "Albert Kropp", "Haie Westhus", "Fredrich Müller", "Stanislaus Katczinsky", "Tjaden"],"tags": ["novel"],"copies": 1, "available": true,"section" : 3} 3 | {"index": {"_index": "library", "_type": "book", "_id": "2"}} 4 | {"title": "Catch-22","author": "Joseph Heller","year": 1961,"characters": ["John Yossarian", "Captain Aardvark","Chaplain Tappman", "Colonel Cathcart", "Doctor Daneeka"],"tags": ["novel"],"copies": 6, "available" : false,"section" : 1} 5 | {"index": {"_index": "library", "_type": "book", "_id": "3"}} 6 | {"title": "The Complete Sherlock Holmes","author": "Arthur Conan Doyle","year": 1936,"characters":["Sherlock Holmes","Dr. Watson", "G. Lestrade"],"tags":[],"copies": 0, "available" : false, "section" : 12} 7 | {"index": {"_index": "library", "_type": "book", "_id": "4"}} 8 | {"title": "Crime and Punishment","otitle": "Преступлéние и наказáние","author": "Fyodor Dostoevsky","year": 1886,"characters": ["Raskolnikov", "Sofia Semyonovna Marmeladova"],"tags": [],"copies": 0, "available" : true} 9 | -------------------------------------------------------------------------------- /data/book_mapping.json: -------------------------------------------------------------------------------- 1 | { 2 | "book" : 3 | { 4 | "_index" : { 5 | "enabled" : true 6 | }, 7 | 8 | "_id" : { 9 | "index": "not_analyzed", 10 | "store" : "yes" 11 | }, 12 | 13 | "properties" : { 14 | "author" : { "type" : "string"}, 15 | "characters" : {"type" : "string"}, 16 | "copies" : {"type" : "long","ignore_malformed":false}, 17 | "otitle" : {"type" : "string"}, 18 | "tags" : {"type" : "string"}, 19 | "title" : {"type" : "string"}, 20 | "year" : {"type" : "long","ignore_malformed":false, "index" : "analyzed"}, 21 | "available" : {"type" : "boolean"} 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /data/comparison.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siddontang/elasticsearch-note/41007e011ffe678bb80234b945bde60feaac7d0f/data/comparison.png -------------------------------------------------------------------------------- /indexing_data.md: -------------------------------------------------------------------------------- 1 | ## Creating indices 2 | 3 | Elasticsearch会自动创建index,譬如 4 | 5 | ``` 6 | http POST :9200/blog/article/1 title="hello world" 7 | ``` 8 | 9 | 如果blog这个index刚开始不存在,Elasticsearch会自动创建。但我们也能够通过如下方式手动创建: 10 | 11 | ``` 12 | http PUT :9200/blog 13 | 14 | HTTP/1.1 200 OK 15 | Content-Length: 21 16 | Content-Type: application/json; charset=UTF-8 17 | 18 | { 19 | "acknowledged": true 20 | } 21 | ``` 22 | 23 | 创建的时候指定一些配置 24 | 25 | ``` 26 | http PUT :9200/blog settings:='{"number_of_shards":1, "number_of_replicas": 2}' 27 | HTTP/1.1 200 OK 28 | Content-Length: 21 29 | Content-Type: application/json; charset=UTF-8 30 | 31 | { 32 | "acknowledged": true 33 | } 34 | 35 | ``` 36 | 37 | 上面我们创建了一个blog索引,使用一个shard,两个replicas。 38 | 39 | ``` 40 | http GET :9200/blog 41 | 42 | HTTP/1.1 200 OK 43 | Content-Length: 191 44 | Content-Type: application/json; charset=UTF-8 45 | 46 | { 47 | "blog": { 48 | "mappings": {}, 49 | "settings": { 50 | "index": { 51 | "creation_date": "1421133862199", 52 | "number_of_replicas": "2", 53 | "number_of_shards": "1", 54 | "uuid": "Vf0y-AZ-Q8uU26u5ptchkQ", 55 | "version": { 56 | "created": "1040299" 57 | } 58 | } 59 | } 60 | } 61 | } 62 | ``` 63 | 64 | 我们也能很方便的删除index 65 | 66 | ``` 67 | http DELETE :9200/blog 68 | 69 | HTTP/1.1 200 OK 70 | Content-Length: 21 71 | Content-Type: application/json; charset=UTF-8 72 | 73 | { 74 | "acknowledged": true 75 | } 76 | 77 | ``` 78 | 79 | ## Mappings 80 | 81 | Schema Mappings可以认为是关系型数据库中的schema,它会定义index的相关结构。 82 | 83 | 下面以一个posts index为例,一个blog post,包含如下结构: 84 | 85 | + Unique identifier 86 | + Name 87 | + Publication date 88 | + Contents 89 | 90 | 对应的mapping文件, posts.json: 91 | 92 | ``` 93 | { 94 | "mappings": { 95 | "post": { 96 | "properties": { 97 | "id" : {"type":"long", "store":"yes"}, 98 | "name" : {"type":"string", "store":"yes", "index":"analyzed"}, 99 | "published" : {"type":"date", "store":"yes"}, 100 | "contents" : {"type":"long", "store":"no", "index":"analyzed"} 101 | } 102 | } 103 | } 104 | } 105 | ``` 106 | 107 | ``` 108 | http POST :9200/posts < posts.json 109 | 110 | HTTP/1.1 200 OK 111 | Content-Length: 21 112 | Content-Type: application/json; charset=UTF-8 113 | 114 | { 115 | "acknowledged": true 116 | } 117 | 118 | ``` 119 | 120 | ``` 121 | http GET :9200/posts 122 | 123 | HTTP/1.1 200 OK 124 | Content-Length: 402 125 | Content-Type: application/json; charset=UTF-8 126 | 127 | { 128 | "posts": { 129 | "mappings": { 130 | "post": { 131 | "properties": { 132 | "contents": { 133 | "index": "analyzed", 134 | "type": "long" 135 | }, 136 | "id": { 137 | "store": true, 138 | "type": "long" 139 | }, 140 | "name": { 141 | "store": true, 142 | "type": "string" 143 | }, 144 | "published": { 145 | "format": "dateOptionalTime", 146 | "store": true, 147 | "type": "date" 148 | } 149 | } 150 | } 151 | }, 152 | ... 153 | } 154 | ``` 155 | 156 | ## Core types 157 | 158 | + String 159 | + Number 160 | + Date 161 | + Boolean 162 | + Binary 163 | 164 | ### Common attributes 165 | 166 | + index_name 167 | + index:analyzed,这个field就会被索引并且能够搜索,no,不能被索引,如果是string,则还有not_analyzed,表明能被索引,不能被analyzed,只能完全匹配 168 | + store:yes,原始值被写入index,no,不写入,默认为no 169 | + boost:默认为1,值越高,表明这个field越重要 170 | + null_value 171 | + copy_to 172 | + include_in_all 173 | 174 | ### String 175 | 176 | + term_vector 177 | + omit_norms 178 | + analyzer:定义indexing和searching使用的analyzer 179 | + index_analyzer 180 | + serach_analyzer 181 | + norms.enabled 182 | + norms.loading 183 | + position_offset_gap 184 | + index_options 185 | + ignore_above 186 | 187 | ### Number 188 | 189 | 包括byte, short, integer, long, float, double 190 | 191 | + precision_step 192 | + ignore_malformed 193 | 194 | ### Boolean 195 | 196 | true or false 197 | 198 | ### Binary 199 | 200 | 在index使用base64编码存储,只有index_name属性 201 | 202 | ### Date 203 | 204 | + format:日期格式,如"YYYY-mm-dd" 205 | + precision_step 206 | + ignore_malformed 207 | 208 | 209 | ### Multi fields 210 | 211 | ``` 212 | "name" : { 213 | "type" : "string", 214 | "fields" : { 215 | "facet" : {"type" : "string", "index":"not_analyzed"} 216 | } 217 | } 218 | ``` 219 | 220 | ### IP Address 221 | 222 | ``` 223 | "address" : {"type" : "ip", "store" : "yes"} 224 | ``` 225 | 226 | ### token_count 227 | 228 | ``` 229 | "address_count" : {"type" : "token_count", "store" : "yes"} 230 | ``` 231 | 232 | ## Analyzers 233 | 234 | 使用[ik](https://github.com/medcl/elasticsearch-analysis-ik)进行中文分词处理 -------------------------------------------------------------------------------- /restful_api.md: -------------------------------------------------------------------------------- 1 | ## Restful API 2 | 3 | Elasticsearch使用restful的架构模型,所以我们能很方便的与其交互。关于REST的详细介绍,请看[这里](http://en.wikipedia.org/wiki/Representational_state_transfer)。 4 | 5 | 后续,会使用[httpie](https://github.com/jakubroztocil/httpie)这个工具来与Elasticsearch进行交互。 6 | 7 | 下面的例子中,我们假设index为blog,而document type为article。 8 | 9 | ## Create 10 | 11 | ``` 12 | http POST :9200/blog/article/1 title="hello elasticsearch" tags:='["elasticsearch"]' 13 | 14 | HTTP/1.1 201 Created 15 | Content-Length: 73 16 | Content-Type: application/json; charset=UTF-8 17 | 18 | { 19 | "_id": "1", 20 | "_index": "blog", 21 | "_type": "article", 22 | "_version": 1, 23 | "created": true 24 | } 25 | ``` 26 | 27 | 我们也可以让Elasticsearch帮我们生成唯一id 28 | 29 | ``` 30 | http POST :9200/blog/article title="hello elasticsearch" tags:='["elasticsearch"]' 31 | 32 | HTTP/1.1 201 Created 33 | Content-Length: 92 34 | Content-Type: application/json; charset=UTF-8 35 | 36 | { 37 | "_id": "AUriBJaUiypP6SwOwQkt", 38 | "_index": "blog", 39 | "_type": "article", 40 | "_version": 1, 41 | "created": true 42 | } 43 | 44 | ``` 45 | 46 | 譬如上面的**AUriBJaUiypP6SwOwQkt**。 47 | 48 | ## Get 49 | 50 | ``` 51 | http GET :9200/blog/article/1 52 | 53 | HTTP/1.1 200 OK 54 | Content-Length: 141 55 | Content-Type: application/json; charset=UTF-8 56 | 57 | { 58 | "_id": "1", 59 | "_index": "blog", 60 | "_source": { 61 | "tags": [ 62 | "elasticsearch" 63 | ], 64 | "title": "hello elasticsearch" 65 | }, 66 | "_type": "article", 67 | "_version": 1, 68 | "found": true 69 | } 70 | ``` 71 | 72 | ## Update 73 | 74 | ### Whole update 75 | 76 | ``` 77 | http PUT :9200/blog/article/1 title="hello elasticsearch" tags:='["elasticsearch", "hello"]' 78 | 79 | HTTP/1.1 200 OK 80 | Content-Length: 74 81 | Content-Type: application/json; charset=UTF-8 82 | 83 | { 84 | "_id": "1", 85 | "_index": "blog", 86 | "_type": "article", 87 | "_version": 2, 88 | "created": false 89 | } 90 | 91 | ``` 92 | 93 | ### Partial update 94 | 95 | ``` 96 | http POST :9200/blog/article/1/_update script="ctx._source.tags+=tag" params:='{"tag":"abc"}' 97 | HTTP/1.1 200 OK 98 | Content-Length: 58 99 | Content-Type: application/json; charset=UTF-8 100 | 101 | { 102 | "_id": "1", 103 | "_index": "blog", 104 | "_type": "article", 105 | "_version": 3 106 | } 107 | ``` 108 | 109 | 110 | ## Delete 111 | 112 | ``` 113 | http DELETE :9200/blog/article/1 114 | HTTP/1.1 200 OK 115 | Content-Length: 71 116 | Content-Type: application/json; charset=UTF-8 117 | 118 | { 119 | "_id": "1", 120 | "_index": "blog", 121 | "_type": "article", 122 | "_version": 4, 123 | "found": true 124 | } 125 | 126 | http HEAD :9200/blog/article/1 127 | HTTP/1.1 404 Not Found 128 | Content-Length: 0 129 | Content-Type: text/plain; charset=UTF-8 130 | ``` 131 | 132 | ## Exists 133 | 134 | Exists: 135 | 136 | ``` 137 | http HEAD :9200/blog/article/1 138 | HTTP/1.1 200 OK 139 | Content-Length: 0 140 | Content-Type: text/plain; charset=UTF-8 141 | ``` 142 | 143 | Not exists: 144 | 145 | ``` 146 | http HEAD :9200/blog/article/2 147 | HTTP/1.1 404 Not Found 148 | Content-Length: 0 149 | Content-Type: text/plain; charset=UTF-8 150 | ``` 151 | 152 | 153 | -------------------------------------------------------------------------------- /searching_data.md: -------------------------------------------------------------------------------- 1 | ## 数据准备 2 | 3 | mapping json 4 | 5 | ``` 6 | http POST :9200/library 7 | 8 | http PUT :9200/library/book/_mapping < data/book_mapping.json 9 | ``` 10 | 11 | bulk data 12 | 13 | ``` 14 | http POS :9200/_bulk < data/book_document.json 15 | ``` 16 | 17 | ## Simple query 18 | 19 | ``` 20 | http GET :9200/library/book/_search query:='{"query_string":{"query":"title:crime"}}' 21 | 22 | HTTP/1.1 200 OK 23 | Content-Length: 446 24 | Content-Type: application/json; charset=UTF-8 25 | 26 | { 27 | "_shards": { 28 | "failed": 0, 29 | "successful": 5, 30 | "total": 5 31 | }, 32 | "hits": { 33 | "hits": [ 34 | { 35 | "_id": "4", 36 | "_index": "library", 37 | "_score": 0.15342641, 38 | "_source": { 39 | "author": "Fyodor Dostoevsky", 40 | "available": true, 41 | "characters": [ 42 | "Raskolnikov", 43 | "Sofia Semyonovna Marmeladova" 44 | ], 45 | "copies": 0, 46 | "otitle": "Преступлéние и наказáние", 47 | "tags": [], 48 | "title": "Crime and Punishment", 49 | "year": 1886 50 | }, 51 | "_type": "book" 52 | } 53 | ], 54 | "max_score": 0.15342641, 55 | "total": 1 56 | }, 57 | "timed_out": false, 58 | "took": 2 59 | } 60 | 61 | ``` 62 | 63 | ## Paging and size 64 | 65 | from and size 66 | 67 | ``` 68 | http GET :9200/library/book/_search query:='{"query_string":{"query":"title:crime"}}' from=20 size=9 69 | 70 | HTTP/1.1 200 OK 71 | Content-Length: 128 72 | Content-Type: application/json; charset=UTF-8 73 | 74 | { 75 | "_shards": { 76 | "failed": 0, 77 | "successful": 5, 78 | "total": 5 79 | }, 80 | "hits": { 81 | "hits": [], 82 | "max_score": 0.15342641, 83 | "total": 1 84 | }, 85 | "timed_out": false, 86 | "took": 1 87 | } 88 | ``` 89 | 90 | ## 返回版本号 91 | 92 | version 93 | 94 | ``` 95 | http GET :9200/library/book/_search query:='{"query_string":{"query":"title:crime"}}' version:='true' 96 | ``` 97 | 98 | ## 限制最低score 99 | 100 | min_score 101 | 102 | ``` 103 | http GET :9200/library/book/_search query:='{"query_string":{"query":"title:crime"}}' min_score:='0.75' 104 | ``` 105 | 106 | ## 返回指定field 107 | 108 | fields 109 | 110 | ``` 111 | http GET :9200/library/book/_search query:='{"query_string":{"query":"title:crime"}}' fields:='["title", "year"]' 112 | ``` 113 | 114 | ## Partial field 115 | 116 | partial_fields,有include和exclude两个属性 117 | 118 | ``` 119 | http GET :9200/library/book/_search query:='{"query_string":{"query":"title:crime"}}' partial_fields:='{"partial1":{"include":["titl*"], "exclude":["chara*"]}}' 120 | 121 | HTTP/1.1 200 OK 122 | Content-Length: 250 123 | Content-Type: application/json; charset=UTF-8 124 | 125 | { 126 | "_shards": { 127 | "failed": 0, 128 | "successful": 5, 129 | "total": 5 130 | }, 131 | "hits": { 132 | "hits": [ 133 | { 134 | "_id": "4", 135 | "_index": "library", 136 | "_score": 0.15342641, 137 | "_type": "book", 138 | "fields": { 139 | "partial1": [ 140 | { 141 | "title": "Crime and Punishment" 142 | } 143 | ] 144 | } 145 | } 146 | ], 147 | "max_score": 0.15342641, 148 | "total": 1 149 | }, 150 | "timed_out": false, 151 | "took": 2 152 | } 153 | ``` 154 | 155 | ## Script fields 156 | 157 | script_fields 158 | 159 | ``` 160 | http GET :9200/library/book/_search query:='{"query_string":{"query":"title:crime"}}' script_fields:='{"correctYear":{"script":"_source.year - 1800"}}' 161 | 162 | HTTP/1.1 200 OK 163 | Content-Length: 223 164 | Content-Type: application/json; charset=UTF-8 165 | 166 | { 167 | "_shards": { 168 | "failed": 0, 169 | "successful": 5, 170 | "total": 5 171 | }, 172 | "hits": { 173 | "hits": [ 174 | { 175 | "_id": "4", 176 | "_index": "library", 177 | "_score": 0.15342641, 178 | "_type": "book", 179 | "fields": { 180 | "correctYear": [ 181 | 86 182 | ] 183 | } 184 | } 185 | ], 186 | "max_score": 0.15342641, 187 | "total": 1 188 | }, 189 | "timed_out": false, 190 | "took": 4 191 | } 192 | ``` 193 | 194 | 给Script传递参数 195 | 196 | ``` 197 | http GET :9200/library/book/_search query:='{"query_string":{"query":"title:crime"}}' script_fields:='{"correctYear":{"script":"_source.year - paramYear", "param":{"paramYear":1800}}}' 198 | ``` 199 | 200 | ## Search Types 201 | 202 | + query_then_fetch,默认的,首先在所有相关的shard上面执行语句,获取相关相关信息用以sort和rank documents,然后在从满足条件的shard里面查询数据。 203 | + query_and_fetch,query在所有的shard上面执行并返回结果 204 | + dfs_query_and_fetch 205 | + dfs_query_then_fetch 206 | + count,只是返回满足条件的文档数量 207 | + scan 208 | 209 | 通过参数search_type指定 210 | 211 | ``` 212 | http GET :9200/library/book/_search query:='{"query_string":{"query":"title:crime"}}' search_type==query_and_fetch 213 | ``` 214 | 215 | ## Term Query 216 | 217 | ``` 218 | http GET :9200/library/book/_search query:='{"term":{"title":"crime"}}' 219 | ``` 220 | 221 | Term因为不可分割,只能是全匹配,并且不会被analyzed 222 | 223 | ## Terms Query 224 | 225 | ``` 226 | http GET :9200/library/book/_search query:='{"terms":{"tags":["novel", "book"], "minimum_match":1}}' 227 | ``` 228 | 229 | minimal_match等于1,只需要一个term匹配就可以了,如果为2,就是两个都需要匹配 230 | 231 | ## match_all Query 232 | 233 | 返回所有的documents 234 | 235 | ``` 236 | http GET :9200/library/book/_search query:='{"match_all":{}}' 237 | ``` 238 | 239 | ## match query 240 | 241 | ``` 242 | http GET :9200/library/book/_search query:='{"match":{"title":"crime and punishment"}}' 243 | ``` 244 | 245 | ## Boolean match query 246 | 247 | + operator: and/or 248 | + analyzer 249 | + fuzziness 250 | + prefix_length 251 | + max_expansions 252 | + zero_terms_query 253 | + cutoff_frequency 254 | 255 | ``` 256 | http GET :9200/library/book/_search query:='{"match":{"title":{"query":"crime and punishment", "operator":"and"}}}' 257 | ``` 258 | 259 | ## match_phrase query 260 | 261 | + slop 262 | + analyzer 263 | 264 | ``` 265 | http GET :9200/library/book/_search query:='{"match_phrase":{"title":{"query":"crime punishment", "slop":1}}}' 266 | ``` 267 | 268 | ## match_phrase_prefix query 269 | 270 | ## multi_match query 271 | 272 | 可以指定多个field进行查询 273 | 274 | ``` 275 | http GET :9200/library/book/_search query:='{"multi_match":{"query":"crime punishment","fields":["title", "otitle"]}}' 276 | ``` 277 | 278 | ## query_string query 279 | 280 | 支持Lucene语法 281 | 282 | ``` 283 | http GET :9200/library/book/_search query:='{"query_string":{"query":"title:crime^10 +title:punishment -otitle:cat +author:(+Fyodor +dostoevsky)", "default_field":"title"}}' 284 | ``` 285 | 286 | + query 287 | + default_field 288 | + default_operator 289 | + analyzer 290 | + allow_leading_wildcard 291 | + lowercase_expand_terms 292 | + enable_position_increments 293 | + fuzzy_max_expansions 294 | + fuzzy_prefix_length 295 | + fuzzy_min_sim 296 | + phrase_slop 297 | + boost 298 | + analyze_wildcard 299 | + auto_generate_phrase_queries 300 | + minimum_should_match 301 | + lenient 302 | 303 | mutli fields 304 | 305 | ``` 306 | http GET :9200/library/book/_search query:='{"query_string":{"query":"title:crime^10 +title:punishment -otitle:cat +author:(+Fyodor +dostoevsky)", "default_field":"title", "use_dis_max": true}}' 307 | ``` 308 | 309 | ## simple_query_string query 310 | 311 | 不同于query_string,对于错误query,不会抛出异常,只会忽略错误的部分 312 | 313 | ## identifiers query 314 | 315 | 只针对id 316 | 317 | ``` 318 | http GET :9200/library/book/_search query:='{"ids":{"values":["1", "10"]}}' 319 | ``` 320 | 321 | 限定document type 322 | 323 | ``` 324 | http GET :9200/library/book/_search query:='{"ids":{"values":["1", "10"], "type": "book"}}' 325 | ``` 326 | 327 | ## prefix query 328 | 329 | ``` 330 | http GET :9200/library/book/_search query:='{"prefix":{"title":"cri"}}' 331 | ``` 332 | 333 | ## fuzzy_like_this query 334 | ## fuzzy_like_this_field query 335 | ## fuzzy query 336 | ## wildcard query 337 | ## more_like_this query 338 | ## more_like_this_field query 339 | 340 | ## range query 341 | 342 | + gte 343 | + gt 344 | + lte 345 | + lt 346 | 347 | ``` 348 | http GET :9200/library/book/_search query:='{"range":{"year":{"gte":1700, "lte":1900}}}' 349 | ``` 350 | 351 | ## dismax query 352 | ## regular expression query 353 | 354 | ## bool query 355 | 356 | + should 357 | + must 358 | + must_not 359 | 360 | ## boosting query 361 | ## constant_score query 362 | ## indices query 363 | 364 | ## Filters 365 | 366 | post_filter 367 | 368 | ``` 369 | http GET :9200/library/book/_search query:='{"match":{"title" : "Catch"}}' post_filter:='{"term":{"year":1961}}' 370 | ``` 371 | 372 | filtered 373 | 374 | ``` 375 | http GET :9200/library/book/_search query:='{"filtered":{"query":{"match":{"title": "Catch"}}, "filter":{"term":{"year":1961}}}}' 376 | ``` 377 | 378 | ## Filter types 379 | 380 | + range 381 | + exists 382 | + missing 383 | + script 384 | + type 385 | + limit 386 | + identifiers 387 | 388 | ## Highlighting 389 | 390 | ``` 391 | http GET :9200/library/book/_search query:='{"term":{"title":"crime"}}' highlight:='{"fields":{"title":{}}}' 392 | ``` 393 | 394 | ## Sort 395 | 396 | asc or desc 397 | 398 | 如果想让某个field排序,一定要在mapping里面指定,否则都会按照score来排序的 399 | --------------------------------------------------------------------------------