ES客户端开发
引入依赖
<dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>${elastic.search.version}</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>transport</artifactId> <version>${elastic.search.version}</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>${elastic.search.version}</version> </dependency> <dependency> <groupId>org.elasticsearch.plugin</groupId> <artifactId>transport-netty4-client</artifactId> <version>${elastic.search.version}</version> </dependency> |
QueryBuilder
QueryBuilder以组合模式将查询块(QueryBuilder)使用must, should等Operator操作符进行组合。
QueryBuilders
org.elasticsearch.index.query. QueryBuilders 提供建立查询块的静态工具方法:
方法名 | ES Query DSL | 说明 |
MatchAllQuery | match_all | 查询全部 |
matchQuery | match | 文本匹配查询 |
multiMatchQuery | multi_match | 针对多个域进行查询 |
matchPhraseQuery | match_phrase | 分析文本转换为短语查询 |
matchPhrasePrefixQuery | match_phrase_prefix | 文本作为前缀匹配 |
disMaxQuery | dis_max | dis_max查询,会将匹配的分数最高的得分作为最终得分 |
idsQuery | ids | 查询多个ID的文档 |
termQuery | term | 精确的术语匹配 |
fuzzyQuery | fuzzy | 相似度查询 |
prefixQuery | prefix | 前缀查询 |
rangeQuery | range | 范围查找 |
wildcardQuery | wildcard | 通配符查找 |
regexpQuery | regexp | 正则查找 |
queryStringQuery | query_string | 使用query查询语句进行查找 |
simpleQueryStringQuery | simple_query_string | 类似于queryStringQuery,查询语句语法更加简单 |
boostingQuery | boosting | 返回文档分数通过正向匹配分数-负向匹配分数 |
boolQuery | Bool | 通过组合查询不同块之间的组合关系进行匹配查询, 包括must、shuold、filter的组合模式 |
nestedQuery | nested | 连接查询,当查询目标域是文档属性中的域(对象属性下的域),需要使用nested查询 |
termsQuery | terms | 精确查询, 类似于term查询, 可以查询多个,和关系数据库的in查询类似。 |
existsQuery | exists | 检查域是否存在 |
示例:
QueryBuilders.matchQuery(“queryField”, “queryValue”);
BoolQueryBuilder
BoolQeuryBuilder 是默认的组合查询, 可以将多个叶子查询或符合查询进行组合条件进行查询。
通过QueryBuilders类的boolQuery静态方法可以获取到BoolQuery的实例:
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
BoolQueryBuilder 对象包含以下四个列表属性,分别对应查询中的must, filter, must_not, shuold四个子块。
private final List<QueryBuilder> mustClauses = new ArrayList(); private final List<QueryBuilder> mustNotClauses = new ArrayList(); private final List<QueryBuilder> filterClauses = new ArrayList(); private final List<QueryBuilder> shouldClauses = new ArrayList(); |
URL bool查询示例:
{ "query": { "bool" : { "must" : { "term" : { "user.id" : "kimchy" } }, "filter": { "term" : { "tags" : "production" } }, "must_not" : { "range" : { "age" : { "gte" : 10, "lte" : 20 } } }, "should" : [ { "term" : { "tags" : "env1" } }, { "term" : { "tags" : "deployed" } } ], "minimum_should_match" : 1, "boost" : 1.0 } } } |
通过BoolQueryBuilder类的must, mustNot, filter, shuold方法将查询字块加入到BoolQueryBuilder相应属性列表中。
must: 类似于AND, 表示匹配查询中必须满足的条件。
mustNot: 查询中不能匹配的条件,该查询字块并不会过滤响应的文档, 而是文档对应分数得分为0
filter:过滤, 匹配指定条件的文档将被过滤,不返回(注意和mustNot的区别)
should: 应该符合的条件, should中条件和must条件的区别在于, should中匹配的条件受,minimum_should_match参数的影响, 注意当shuold和must混合使用时,默认的minimum_should_match=0,因此shuold中制定的过滤条件不产生作用。 需指定minimum_should_match才能生效。
queryBuilder.minimumShouldMatch(1);
示例:
queryBuilder.must(QueryBuilders.matchQuery(dimensionCode, dimensionValue));
查询示例
multiSearch API
GET my-index-000001/_msearch { } {"query" : {"match" : { "message": "this is a test"}}} {"index": "my-index-000002"} {"query" : {"match_all" : {}}} |
客户端开发示例
创建链接客户端RestHighLevelClient
//创建RestHighLevelClient Settings settings = Settings.builder().put("client.transport.sniff", false).put("cluster.name", clusterName).build(); String scheme = ssl ? "https" : "http"; List<String> urls = Arrays.asList(esUrls.split(",")); RestHighLevelClient client; if (security && !StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)) { //带用户名和密码的客户端 CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password)); client = new RestHighLevelClient(RestClient.builder((Node[])urlsToNodes(urls, scheme).toArray(new Node[0])).setHttpClientConfigCallback((httpClientBuilder) -> { return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider).setKeepAliveStrategy((response, context) -> { return TimeUnit.MINUTES.toMillis(1L); }); })); } else { client = new RestHighLevelClient(RestClient.builder((Node[])urlsToNodes(urls, scheme).toArray(new Node[0])).setHttpClientConfigCallback((httpClientBuilder) -> { return httpClientBuilder.setKeepAliveStrategy((response, context) -> { return TimeUnit.MINUTES.toMillis(1L); }); })); } return client; |
构建和执行查询
//构建multiSearch请求对象 MultiSearchRequest msr = new MultiSearchRequest(); Iterator buildIterator = queryBuilders.iterator(); //组装multiSearch while(buildIterator.hasNext()) { QueryBuilder queryBuilder = (QueryBuilder)buildIterator.next(); SearchRequest searchRequest = new SearchRequest(new String[]{indexName}); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(queryBuilder); searchSourceBuilder.trackTotalHits(true); searchSourceBuilder.size(10000000); searchRequest.source(searchSourceBuilder); msr.add(searchRequest); } try { MultiSearchResponse response = client.msearch(msr, requestOptions); return this.multiResponseToMap(response); } catch (Exception e) { } |
排序和分页
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchSourceBuilder 中指定排序和分页
public SearchSourceBuilder sort(String name, SortOrder order);
public SearchSourceBuilder from(int from) {
只有数字、日期、ID类型的属性可以排序。
ES 类型
字符串类型:text, keyword。 两者的区别在于keyword被当成一个整体, 不会被分词器进行分析索引。
数值类型:long, integer, short, byte, double, float, half_float, scaled_float
日期类型:date
布尔值类型:boolean
二进制类型:binary
对象、数组等。