RestHighLevelClient实现ElasticSearch关联查询之父子文档今天分享,承接上一篇内容:
DSL操作关联查询
这篇我们通过javaAPI的方式实现:
一、springboot 配置
1、pom文件引用:
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.9.3</version>
<exclusions>
<exclusion>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
</exclusion>
<exclusion>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.9.3</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.9.3</version>
</dependency>
<!-- elasticsearch 新版本官方sdk,版本号需与使用的es版本一致 -->
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>7.17.0</version>
</dependency>
2、初始化配置es操作类
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ElasticSearchConfig {
@Bean
public RestHighLevelClient restHighLevelClient(){
RestClientBuilder builder=RestClient.builder(
// new HttpHost("116.204.80.158", 9200, "http"),
new HttpHost("116.204.80.155", 9200, "http"));
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("elastic", "123456"));
builder.setHttpClientConfigCallback(f -> f.setDefaultCredentialsProvider(credentialsProvider));
RestHighLevelClient client = new RestHighLevelClient( builder);
return client;
}
}
3、业务层引用
@Qualifier("restHighLevelClient")
@Autowired
private RestHighLevelClient client;
private static final String indexName = "test_nandao_index";
private static final String tableName = "UserInfo";
private static final String workTableName = "WorkInfo";
private static final String schoolTableName = "SchoolInfo";
private static final String UserWorkRelation = tableName+"_"+workTableName+"_relation";
二、核心伪代码
1、创建父子索引
@Override
public boolean createIndex(String index) throws IOException {
//创建json数
XContentBuilder mapping = XContentFactory.jsonBuilder()
.startObject()
.startObject("properties")
.startObject("content")
.field("type","text")
.endObject()
.startObject("title")
.field("type","text")
.endObject()
.startObject(tableName+"_"+workTableName+"_relation")
.field("type","join")
.startObject("relations")
// .field("blog","comment")
.field(tableName,workTableName)
.endObject()
.endObject()
.endObject()
.endObject();
CreateIndexRequest request = new CreateIndexRequest(index)
.settings(Settings.builder()
.put("number_of_shards", 2)
.put("number_of_replicas", 1)
.build())
.mapping(mapping)
;
//1.创建索引请求
// CreateIndexRequest request = new CreateIndexRequest(index);
String string = request.aliases().toString();
//2.客户端执行请求IndicesClient,请求后获得相应
log.info("请求:{}", JSONObject.toJSONString(request));
log.info("请求:{}",request.toString());
CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
log.info("返回:{}", JSON.toJSONString(response));
return response.isAcknowledged();
}
kibana查看
GET /nandao_parent_sub_index/_mapping
2、判断索引是否存在
@Override
public boolean isExit(String index) throws IOException {
GetIndexRequest request = new GetIndexRequest(index);
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
return exists;
}
3、删除索引
@Override
public boolean delete(String index) throws IOException {
DeleteIndexRequest request = new DeleteIndexRequest(index);
AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
return delete.isAcknowledged();
}
4、添加父文档
@Override
public boolean addDocument(String index, String id, Object object) throws IOException {
IndexRequest request = new IndexRequest(index);
//规则 一般的文档形如 put /index/_doc/1
//request.id(id);//如果不设置id的话会自动分配id
request.timeout("1s");//设置超时时间
System.out.println("JSON.toJSONString(object):"+ JSON.toJSONString(object));
//将我们的数据放入请求Json中
JSONObject jsonObject = (JSONObject) JSONObject.toJSON(object);
//添加join关联索引
JSONObject relationObject = new JSONObject();
// relationObject.put(tableName,workTableName);
relationObject.put("name",tableName);
jsonObject.put(UserWorkRelation,relationObject);
request.source(JSON.toJSONString(jsonObject), XContentType.JSON);
log.info("请求:{}", JSONObject.toJSONString(request));
log.info("请求1:{}", JSON.toJSONString(request));
log.info("请求2:{}", JSON.toJSONString(jsonObject));
//客户端发送请求,获取相应的结果
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
return response.getShardInfo().getSuccessful()>0?true:false;
}
5、更新父文档
@Override
public boolean updateDocument(UserInfoVo user, String index, String id) throws IOException {
UpdateRequest request = new UpdateRequest(index, id);
request.timeout("1s");
//将我们的数据放入请求Json中
JSONObject jsonObject = (JSONObject) JSONObject.toJSON(user);
//添加join关联索引
JSONObject relationObject = new JSONObject();
// relationObject.put(tableName,workTableName);
relationObject.put("name",tableName);
jsonObject.put(UserWorkRelation,relationObject);
request.doc(JSON.toJSONString(jsonObject), XContentType.JSON);
UpdateResponse update = client.update(request, RequestOptions.DEFAULT);
return update.getShardInfo().getSuccessful()>0?true:false;
}
6、添加子文档
@Override
public boolean addDocumentSub(String index, String parentId, Object object) throws IOException {
IndexRequest request = new IndexRequest(index).routing(parentId);//设置索引和路由
//规则 一般的文档形如 put /index/_doc/1
//request.id(id);//如果不设置id的话会自动分配id
request.timeout("1s");//设置超时时间
System.out.println("JSON.toJSONString(object):"+ JSON.toJSONString(object));
//将我们的数据放入请求Json中
JSONObject jsonObject = (JSONObject) JSONObject.toJSON(object);
//添加join关联索引
JSONObject relationObject = new JSONObject();
relationObject.put("name",workTableName);
relationObject.put("parent",parentId);
jsonObject.put(UserWorkRelation,relationObject);
request.source(JSON.toJSONString(jsonObject), XContentType.JSON);
log.info("请求:{}", JSONObject.toJSONString(request));
log.info("请求1:{}", JSON.toJSONString(request));
log.info("请求2:{}", JSON.toJSONString(jsonObject));
//客户端发送请求,获取相应的结果
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
return response.getShardInfo().getSuccessful()>0?true:false;
}
创建普通文档
@Override
public boolean createDocument(String index, Object object) throws IOException {
IndexRequest request = new IndexRequest(index);
//规则 一般的文档形如 put /index/_doc/1
// request.id(id);//如果不设置id的话会自动分配id
request.timeout("1s");//设置超时时间
System.out.println("JSON.toJSONString(object):"+ JSON.toJSONString(object));
//将我们的数据放入请求Json中
request.source(JSON.toJSONString(object), XContentType.JSON);
//客户端发送请求,获取相应的结果
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
return response.getShardInfo().getSuccessful()>0?true:false;
}
7、判断是否是doc格式
@Override
public boolean isdocuexit(String index, String id) throws IOException {
GetRequest getRequest = new GetRequest(index,id);
//不获取返回的_source上下文
getRequest.fetchSourceContext(new FetchSourceContext(false));
getRequest.storedFields("_none_");
return client.exists(getRequest, RequestOptions.DEFAULT);
}
8、根据id和索引查询
@Override
public String getDoucumment(String index, String id) throws IOException {
GetRequest getRequest = new GetRequest(index, id);
GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);
return response.getSourceAsString();
}
9、根据父id查询
@Override
public String getDoucummentByParentId(String index, TreeMap<String, Object> content,String parentId) throws IOException {
SearchRequest searchRequest = new SearchRequest(index);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
ParentIdQueryBuilder build = JoinQueryBuilders.parentId("WorkInfo",parentId);
sourceBuilder.query(build);
//将查询条件放入需要查询中
searchRequest.source(sourceBuilder);
System.out.println("dsl===1==="+sourceBuilder.toString());
//获取相应的数据
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = searchResponse.getHits().getHits();
// SearchRequest searchRequest = new SearchRequest(index);
searchResponse.getHits().forEach(hi ->{
log.info("查询结果:{}",hi.getSourceAsString());
});
return hits.toString();
}
对应DSL语句
POST /nandao_parent_sub_index/_search
{
"query": {
"parent_id": {
"type": "WorkInfo",
"id": "tYTxYoUBJlO7GBNmNPml"
}
}
}
10、Has Child 查询,返回父文档
@Override
public String getDoucummentHasChild(String userName, String index) throws IOException {
SearchRequest searchRequest = new SearchRequest(index);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
HasChildQueryBuilder build = JoinQueryBuilders.hasChildQuery("WorkInfo",QueryBuilders.matchQuery("userName", "Jack"), ScoreMode.None);
sourceBuilder.query(build);
//将查询条件放入需要查询中
searchRequest.source(sourceBuilder);
System.out.println("dsl===1==="+sourceBuilder.toString());
//获取相应的数据
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = searchResponse.getHits().getHits();
searchResponse.getHits().forEach(hi ->{
log.info("查询结果:{}",hi.getSourceAsString());
});
return hits.toString();
}
对应DSL语句:
POST /nandao_parent_sub_index/_search
{
"query": {
"has_child": {
"type": "WorkInfo",
"query": {
"match": {
"userName": "Jack"
}
}
}
}
}
11、Has parent 查询,返回子文档
@Override
public String getDoucummentHasParent(String userName, String index) throws IOException {
SearchRequest searchRequest = new SearchRequest(index);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
HasParentQueryBuilder build= JoinQueryBuilders.hasParentQuery("UserInfo", QueryBuilders.matchQuery("userName", "wangwu"), false);
sourceBuilder.query(build);
//将查询条件放入需要查询中
searchRequest.source(sourceBuilder);
System.out.println("dsl===1==="+sourceBuilder.toString());
//获取相应的数据
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = searchResponse.getHits().getHits();
searchResponse.getHits().forEach(hi ->{
log.info("查询结果:{}",hi.getSourceAsString());
});
return hits.toString();
}
对应DSL语句:
GET /nandao_parent_sub_index/_search
{
"query": {
"has_parent": {
"parent_type": "UserInfo",
"query": {
"match": {
"userName": "wangwu"
}
}
}
}
}
12、通过索引查
@Override
public String getAllDoucummentByIndex(String index) throws IOException {
SearchRequest searchRequest = new SearchRequest(index);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = searchResponse.getHits().getHits();
return hits.toString();
}
13、通过索引和id删除文档
@Override
public boolean deleteDocument(String index, String id) throws IOException {
DeleteRequest request = new DeleteRequest(index,id);
request.timeout("1s");
DeleteResponse deleteResponse = client.delete(request, RequestOptions.DEFAULT);
return deleteResponse.getShardInfo().getSuccessful()>0?true:false;
}
14、批量添加文档
@Override
public boolean addmoredocument(List<Object> list, String index, String id) throws IOException {
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("1s");
//批量处理请求
for (int i=0;i<list.size();i++){
bulkRequest.add(
new IndexRequest(index)
//.id(id)
.source(JSON.toJSONString(list.get(i)), XContentType.JSON));
}
BulkResponse responses = client.bulk(bulkRequest, RequestOptions.DEFAULT);
//是否失败 false-没有失败
return responses.hasFailures()?false:true;
}
15、termQuery
@Override
public List<Map<String, Object>> termQuery(String index, TreeMap<String, Object> content, int size, int from, boolean ishigh) throws IOException {
SearchRequest searchRequest = new SearchRequest(index);
//构建查询条件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
System.out.println(content.firstKey());
//查询条件
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(content.firstKey(),content.get(content.firstKey()));
sourceBuilder.query(termQueryBuilder);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//获取多少条数据
sourceBuilder.size(size);
//从第几行开始
sourceBuilder.from(from);
//是否要将查询的结果中将搜索的关键词高亮
if (ishigh){
HighlightBuilder highlightBuilder = new HighlightBuilder();
//设置高亮的属性
highlightBuilder.field(content.firstKey());
//也可以自定义高亮的样式,这里我使用的是默认的方式
sourceBuilder.highlighter(highlightBuilder);
}
System.out.println("dsl===1==="+sourceBuilder.toString());
//将查询条件放入需要查询中
searchRequest.source(sourceBuilder);
//获取相应的数据
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = searchResponse.getHits().getHits();
ArrayList<Map<String, Object>> result = new ArrayList<>();
for (SearchHit searchHit:hits){
Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
//获取高亮的信息
HighlightField property = highlightFields.get(content.firstKey());
//查询的元素数据(没有高亮)
Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
if (ishigh){
if (property!=null){
Text[] fragments = property.fragments();
String n_title = "";
for (Text text:fragments){
n_title += text;
}
sourceAsMap.put(content.firstKey(),n_title);
}
}
result.add(sourceAsMap);
}
System.out.println("result==1===:"+result);
return result;
}
16、matchQuery
@Override
public List<Map<String, Object>> matchQuery(String index, TreeMap<String, Object> content, int size, int from, boolean ishigh) throws IOException {
SearchRequest searchRequest = new SearchRequest(index);
//构建查询条件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//查询条件
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(content.firstKey(),content.get(content.firstKey()));
sourceBuilder.query(matchQueryBuilder);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//获取多少条数据
sourceBuilder.size(size);
//从第几行开始
sourceBuilder.from(from);
//是否要高亮
if (ishigh){
HighlightBuilder highlightBuilder = new HighlightBuilder();
//设置高亮的属性
highlightBuilder.field(content.firstKey());
//也可以自定义高亮的样式,这里我使用的是默认的方式
sourceBuilder.highlighter(highlightBuilder);
}
System.out.println("dsl===2==="+sourceBuilder.toString());
//将查询条件放入需要查询中
searchRequest.source(sourceBuilder);
//获取相应的数据
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = searchResponse.getHits().getHits();
ArrayList<Map<String, Object>> result = new ArrayList<>();
for (SearchHit searchHit:hits){
Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
//获取高亮的信息
HighlightField property = highlightFields.get(content.firstKey());
//查询的元素数据(没有高亮)
Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
System.out.println("sourceAsMap===2==="+sourceAsMap);
if (ishigh){
if (property!=null){
Text[] fragments = property.fragments();
String n_title = "";
for (Text text:fragments){
n_title += text;
}
sourceAsMap.put(content.firstKey(),n_title);
}
}
result.add(sourceAsMap);
}
System.out.println("result==2===:"+result);
return result;
}
17、boolmustQuery
@Override
public List<Map<String, Object>> boolmustQuery(String index, TreeMap<String, Object> content, int size, int from, boolean ishigh) throws IOException {
SearchRequest searchRequest = new SearchRequest(index);
//构建查询条件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//查询条件
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
Set keys = content.keySet();
for (Object key:keys){
//将要查询的条件加入
boolQueryBuilder.must(QueryBuilders.termQuery((String) key,content.get(key)));
}
sourceBuilder.query(boolQueryBuilder);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//获取多少条数据
sourceBuilder.size(size);
//从第几行开始
sourceBuilder.from(from);
System.out.println("dsl===3==="+sourceBuilder.toString());
//将查询条件放入需要查询中
searchRequest.source(sourceBuilder);
//获取相应的数据
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = searchResponse.getHits().getHits();
ArrayList<Map<String, Object>> result = new ArrayList<>();
for (SearchHit searchHit:hits){
Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
//获取高亮的信息
HighlightField property = highlightFields.get(content.firstKey());
//查询的元素数据(没有高亮)
Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
System.out.println("sourceAsMap===2==="+sourceAsMap);
if (ishigh){
if (property!=null){
Text[] fragments = property.fragments();
String n_title = "";
for (Text text:fragments){
n_title += text;
}
sourceAsMap.put(content.firstKey(),n_title);
}
}
result.add(sourceAsMap);
}
System.out.println("result==3===:"+result);
return result;
}
到此关联关系处理基本分享完毕,同时也可以参考这篇文章:
es父子查询处理文章来源:https://www.toymoban.com/news/detail-690248.html
下篇我们分析es的理论与架构组成敬请期待!文章来源地址https://www.toymoban.com/news/detail-690248.html
到了这里,关于RestHighLevelClient实现ElasticSearch关联查询之父子文档的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!