ElasticSearch的一些用法总结
《ElasticSearch的一些用法总结》,2016年7月25日
一、ElasticSearch简单搜索:
1、在特定索引和所有索引中搜索:
- /_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中搜索
例子: - eg:http://192.168.16.3:9200/_search 在所有索引中搜索
- eg:http://192.168.16.3:9200/xxx/_search 在xxx索引中搜索
- eg:http://192.168.16.3:9200/xxx/xxx_info/_search 在xxx索引中类型为xxx_info中搜索
2、搜索所有类型为tweet并且在tweet字段中包含elasticsearch字符的结果:
GET /_all/tweet/_search?q=tweet:elasticsearch
例子:
eg:http://192.168.16.3:9200/xxx/xxx_info/_search?q=number:5266838 搜索number字段为5266838的结果
eg:http://192.168.16.3:9200/xxx/xxx_info/_search?q=case_type:案件&trial_procedure:一审
3、搜索name字段中包含”john”和tweet字段包含”mary”的结果
使用:+name:john +tweet:mary
说明:”+”前缀表示语句匹配条件必须被满足。类似的”-“前缀表示条件必须不被满足。所有条件如果没有+或-表示是可选的——匹配越多,相关的文档就越多
编码后:GET /_search?q=%2Bname%3Ajohn+%2Btweet%3Amary
4、我们需要查询内容要完全匹配其内容。避免被分词,在查询内容前面加上双引号
eg:http://192.168.16.3:9200/xxx/xxx_info/_search?q=text:”北京市汽车运输有限公司”
如果不加引号,默认是会进行分词检索的,也就是搜到匹配:北京市、汽车、运输、有限公司词语的结果。更多高级分词检索用法请查看下面介绍:《二、请求体高级搜索API》
5、分页搜索
和SQL使用LIMIT关键字返回只有一页的结果一样,Elasticsearch接受from和size参数:
- size: 结果数,默认10
- from: 跳过开始的结果数,默认0
- 如果你想每页显示5个结果,页码从1到3,那请求如下:
- GET /_search?size=5
- GET /_search?size=5&from=5
- GET /_search?size=5&from=10
例子:
eg:http://192.168.16.3:9200/xxx/xxx_info/_search?q=text:”北京市汽车运输有限公司”&size=5&from=10 。搜索结果总条数是在json数据中total字段
6、稍复杂的搜索
在所有索引中,name字段包含”mary”或”john”,date晚于2014-09-10,_all字段包含”aggregations”或”geo”
使用:+name:(mary john) +date:>2014-09-10 +(aggregations geo)
编码后:?q=%2Bname%3A(mary+john)+%2Bdate%3A%3E2014-09-10+%2B(aggregations+geo)
7、注意
- 查询字符串中一个细小的语法错误,像-、:、/或”错位就会导致返回错误而不是结果。
- 不建议直接暴露查询字符串搜索给用户,除非这些用户对于你的数据和集群可信。
- 生产环境中一般依赖全功能的请求体搜索API,它能完成更多复杂的检索、索引、等等的事情
二、请求体高级搜索API(部分用法,更多请查看文档):
1、term
代表完全匹配,即不进行分词器分析,文档中必须包含整个搜索的词汇
1 2 3 4 5 6 7 |
{ "query": { "term": { "content": "汽车保养" } } } |
查出的所有文档都包含”汽车保养”这个词组的词汇。
使用term要确定的是这个字段是否“被分析”(analyzed),默认的字符串是被分析的。
2、match
查询和”我的宝马多少马力”这个查询语句匹配的文档。
1 2 3 4 5 6 7 8 9 |
{ "query": { "match": { "content" : { "query" : "我的宝马多少马力" } } } } |
上面的查询匹配就会进行分词,比如”宝马多少马力”会被分词为”宝马 多少 马力”, 所有有关”宝马 多少 马力”, 那么所有包含这三个词中的一个或多个的文档就会被搜索出来。并且根据lucene的评分机制(TF/IDF)来进行评分。
3、match_phrase
比如上面一个例子,一个文档”我的保时捷马力不错”也会被搜索出来,那么想要精确匹配所有同时包含”宝马 多少 马力”的文档怎么做?就要使用 match_phrase 了
1 2 3 4 5 6 7 8 9 |
{ "query": { "match_phrase": { "content" : { "query" : "我的宝马多少马力" } } } } |
完全匹配可能比较严,我们会希望有个可调节因子,少匹配一个也满足,那就需要使用到slop。
1 2 3 4 5 6 7 8 9 10 |
{ "query": { "match_phrase": { "content" : { "query" : "我的宝马多少马力", "slop" : 1 } } } } |
4、multi_match
如果我们希望两个字段进行匹配,其中一个字段有这个文档就满足的话,使用multi_match
1 2 3 4 5 6 7 8 |
{ "query": { "multi_match": { "query" : "我的宝马多少马力", "fields" : ["title", "content"] } } } |
5、best_fields
意思就是完全匹配”宝马 发动机”的文档评分会比较靠前,如果只匹配宝马的文档评分乘以0.3的系数
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "query": { "multi_match": { "query": "我的宝马发动机多少", "type": "best_fields", "fields": [ "tag", "content" ], "tie_breaker": 0.3 } } } |
6、most_fields
越多字段匹配的文档评分越高
1 2 3 4 5 6 7 8 9 10 11 12 |
{ "query": { "multi_match": { "query": "我的宝马发动机多少", "type": "most_fields", "fields": [ "tag", "content" ] } } } |
7、cross_fields
这个词条的分词词汇是分配到不同字段中的
1 2 3 4 5 6 7 8 9 10 11 12 |
{ "query": { "multi_match": { "query": "我的宝马发动机多少", "type": "cross_fields", "fields": [ "tag", "content" ] } } } |
8、must,should,must_not
如果我们想要请求”content中带宝马,但是tag中不带宝马”这样类似的需求,就需要用到bool联合查询。
联合查询就会使用到must,should,must_not三种关键词。
这三个可以这么理解
must: 文档必须完全匹配条件
should: should下面会带一个以上的条件,至少满足一个条件,这个文档就符合should
must_not: 文档必须不匹配条件
比如上面那个需求:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{ "query": { "bool": { "must": { "term": { "content": "宝马" } }, "must_not": { "term": { "tags": "宝马" } } } } } |
三、搜索返回JSON数据:
took:
1、是整个搜索请求花费的毫秒数
timeout:
1、查询超时与否。一般的,搜索请求不会超时。如果响应速度比完整的结果更重要,你可以定义timeout参数为10或者10ms(10毫秒),或者1s(1秒)
写法如下:GET /_search?timeout=10ms
hits:
1、total字段来表示匹配到的文档总数
2、max_score指的是所有文档匹配查询中_score的最大值。
3、hits数组还包含了匹配到的前10条数据。
4、_score表示搜索到的结果,相关性得分,它衡量了文档与查询的匹配程度。默认的,返回的结果中关联性最大的文档排在首位;这意味着,它是按照_score降序排列的。当我们没有指定任何查询,所以所有文档的相关性是一样的,因此所有结果的_score都是取得一个中间值1
《ElasticSearch的一些用法总结》 Copyright:cpp.cloudcpp.com Share、Open- C/C++程序员之家