(本文档基于ElasticSearch V2.4版本)
ES 自己设计了一套Query DSL语法来进行数据Query检索,实际使用中,我们使用Java Query API即可。
1. Client
所有操作都能通过 Client 对象执行,Client中的索引和删除操作可以Bulk执行。
Client分两种,可以初始化一个本地NodeClient,基本上这种使用场景只存在于单元测试中。或者创建一个TransportClient,以轮询的方式和集群通信,是生产环境常用做法。
2. Client 索引示例
import static org.elasticsearch.common.xcontent.XContentFactory.*; IndexResponse response = client.prepareIndex("twitter", "tweet", "1"). setSource(jsonBuilder(). startObject(). field("user", "kimchy"). field("postDate", new Date()). field("message", "trying out Elasticsearch"). endObject()). execute(). actionGet();
IndexResponse的结构如下
// Index name
String _index = response.getIndex();
// Type name
String _type = response.getType();
// Document ID (generated or not)
String _id = response.getId();
// Version (if it's the first time you index this document, you will get: 1)
long _version = response.getVersion();
基于Spring的Web项目,建议直接使用Spring Data ElasticSearch
来建立索引。
3. 常用的Query
ES提供Query及其配套的QueryBuilder,在上一篇文章《使用ElasticSearch快速搭建数据搜索服务》中有提到,在基于Spring的Web项目中,可以非常方便利用Spring Data ElasticSearch封装的ElasticsearchTemplate
来完成搜索,简单代码示例如下:
private ElasticsearchTemplate et; QueryBuilder queryBuilder = matchQuery("name", text); SearchQuery searchQuery = new NativeSearchQueryBuilder(). withQuery(queryBuilder). withPageable(pageRequest). withMinScore(0.01f). build();return et.queryForPage(searchQuery, Item.class);
在上面的示例中,使用了ES提供的matchQuery
,这是一个全文检索最常用的Query,详细情况会在下文介绍。
3.1 matchAllQuery
最简单的一个Query,能返回所有数据。也是基本上用不到的一个Query.
3.2 Term level queries
- 最常用的Query之一,和Mysql的
Select * from * where x=y
用法相似。 - 包含
TermQuery
,TermsQuery
等,主要是处理结构化字段 number,date,enum等。
3.3 matchQuery
最标准最常用的一个Full Text检索的Query,支持分词和模糊匹配等
一共三种Query Type,默认的是boolean,表示会根据查询text生成一个bool query的组合(因为Text被分词之后,会被拆分成多个Term),组合默认的operator是or,用minimum_should_match来控制最小命中数。analyzer参数和lenient参数可以设置,后者设置为True用来处理类型的兼容,例如数字和字符串的比较。前者用来设置分词用到的analyzer。
Query Type还有两种:phrase
和phrase_prefix
。顾名思义是基于短语的Query,查询文档中是否包含特定的短语,可以通过slot参数来设定跳转值。比如搜索“yellow submarine”的phrase Query,如果文档完全包含”yellow submarine“,就能被检索出来,但不设置slop时,”yellow big submarine“无法检出,slop指的是两个Term的位置之间允许的最大间隔距离,当slop=1时,两个term之间可以允许间隔一个单词。
在boolean type里,Fuzziness用来处理模糊匹配,是一个枚举变量,默认是AUTO,可以设置数字0,1,2等来确定查询时字符串编辑距离的相似度。
// 设置至少50%的匹配度
String minimum_should_match = "50%";
3.4 Mulit Match Query
能同时匹配对多个Field的匹配,在多个fields的组合上,有多种type供选择,比较有意思的是cross_fields
, 将所有的fields融合成一个,然后统一处理。具体type如下所示:
best_fields
:默认类型。特别适用于当希望尽可能多的words命中在同一个field中时,且最终_score会取自“表现最好”的那个field。most_fields
:特别适用于文档的多个fields都可能包含检索words时,_score会来自各个fields的“求和”cross_fields
:会把文档的多个fields“合并”成一个field看待,适用于检索word分布在多个field的情况。官方示例,检索“Will Smith”,可能Will在 first_name的field,而Smith在second_name的field.
3.5 Bool Query
Bool Query能把多个Query组合起来(如果你熟悉Lucence的话,它就是对应Lucence的BooleanQuery
的),组合规则有以下几种:
must
:多个Query之间是“与”条件should
:多个Query之间是“或”条件,可以通过minimum_should_match
来约束最少满足条件。must_not
:Query之间是“非”条件filter
:作用与must
相同,区别是filter
的结果不参与score计算
bool query也是可以组合bool query,从而实现复杂的检索逻辑。
4. 结论
最常用的Query是TermQuery
(结构化字段)、matchQuery
(标准Full Text检索)和boolQuery
(与、或的组合)。基于Spring的Web项目建议使用Spring Data ElasticSearch
的封装来索引和检索数据。




