elasticsearch 关联查询
父-子关系文档
父-子关系文档 在实质上类似于 nested model :允许将一个对象实体和另外一个对象实体关联起来。 而这两种类型的主要区别是:在 nested objects 文档中,所有对象都是在同一个文档中,而在父-子关系文档中,父对象和子对象都是完全独立的文档。
父-子关系的主要作用是允许把一个 type 的文档和另外一个 type 的文档关联起来,构成一对多的关系:一个父文档可以对应多个子文档 。与 nested objects 相比,父-子关系的主要优势有:
更新父文档时,不会重新索引子文档。
创建,修改或删除子文档时,不会影响父文档或其他子文档。这一点在这种场景下尤其有用:子文档数量较多,并且子文档创建和修改的频率高时。
子文档可以作为搜索结果独立返回。
Elasticsearch 维护了一个父文档和子文档的映射关系,得益于这个映射,父-子文档关联查询操作非常快。但是这个映射也对父-子文档关系有个限制条件:父文档和其所有子文档,都必须要存储在同一个分片中。
我使用的是es5.6,es6.0版本以上一个索引对应一个type
1.在es中查询父子级关系
创建父子级关系
PUT user_test
{
"mappings": {
"dept": {
"properties": {
"dname":{
"type": "text"
}
}
},
"user":{
"_parent": {
"type": "dept"
},
"properties": {
"deptId":{
"type": "text"
},
"username":{
"type": "text"
},
"age":{
"type": "integer"
}
}
}
}
}
创建了一个公司的索引 包括部门和用户两个类型
新增一个父级数据
POST company/dept/
{
"dname":"开发部"
}
新增一个子级数据
POST company/user?parent=
{
"uid":"",
"uname":"王五",
"age":10 }
以子级查
GET company/user/_search
{
"query": {
"has_parent": {
"parent_type": "dept",
"query": {
"term": {
"dname":"开"
}
},"inner_hits":{}
}
}
}
以父级查
GET company/dept/_search
{
"query": {
"has_child": {
"type": "user",
"query": {
"match": {
"uname":"里斯"
}
},"inner_hits":{}
}
}
}
用inner_hits则可以把父子文档同时返回——既返回,不加inner_hits只返回一个type里的数据。inner_hits默认只查询3条数据,可以自定义设置from 和size。
如果父子级同时有查询条件,用bool作为复合查询
GET company/dept/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"dname": {
"value": "开"
}
}
},{
"has_child": {
"type": "user",
"query": {
"match": {
"uname":"张"
}
},"inner_hits":{}
}
} ]
}
}
}
2.java项目中查询
实体类
1.部门
@Document(indexName = "user_test",type = "dept")
public class Department {
@Id
private String id;
private String dname;
}
2.用户
@Document(indexName = "user_test",type = "user")
public class User {
@Id
private String id;
@Parent(type = "dept")
private String deptId;
private String uname;
private Integer age;
}
使用ElasticsearchTemplate
1查询父级数据
QueryBuilder qb=JoinQueryBuilders.hasChildQuery("user",QueryBuilders.matchAllQuery(),ScoreMode.None);
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withIndices("user_test")
.withQuery(qb)
.build();
List<Department> depts= elasticsearchTemplate.queryForList(searchQuery,Department.class);
ScoreMode:评分模式min,max,sum,avg或none
2.查询子级数据
QueryBuilder qb=JoinQueryBuilders.hasParentQuery("dept",QueryBuilders.matchQuery("dname","开"),false);
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withIndices("user_test")
.withQuery(qb)
.build();
List<User> users= elasticsearchTemplate.queryForList(searchQuery,User.class);
评分功能:这has_parent也有得分支持。默认值是false忽略父文档的分数
官方参考:https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-has-parent-query.html
查询父子级全部数据
QueryBuilder qb = JoinQueryBuilders.hasChildQuery(
"user", //要查询的子类型
QueryBuilders.matchQuery("uname.keyword","张三"),
ScoreMode.None
).innerHit(new InnerHitBuilder());
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withIndices("user_test")
.withQuery(qb)
.build();
List<DeptVO> depts= elasticsearchTemplate.query(searchQuery, searchResponse -> {
SearchHits hits = searchResponse.getHits();
List<DeptVO> list = new ArrayList<>();
Arrays.stream(hits.getHits()).forEach(h -> {
Map<String, Object> source = h.getSource();
SearchHits innerHitsMap=h.getInnerHits().get("user");//获取子级数据
List<User> user1s=Arrays.stream(innerHitsMap.getHits()).map(innerH -> {
Map<String, Object> innerSource = innerH.getSource();
return new User(innerSource.get("uname").toString(),Integer.valueOf(innerSource.get("age").toString()));
}).collect(Collectors.toList());
list.add(new DeptVO(source.get("dname").toString(),user1s));
});
return list;
});
JoinQueryBuilders.hasChildQuery().innerHit(new InnerHitBuilder())的.innerHit(new InnerHitBuilder())与es查询一样
elasticsearch 关联查询的更多相关文章
- ElasticSearch关联查找
ElasticSearch是一个基于Lucene的开源搜索引擎,支持全文检索,提供restful接口.在ES中,提供了类似于MongoDB的面向文档存储服务,这种面向文档的存储非常灵活,但是文档与文档 ...
- elasticsearch 连接查询 基于es5.1.1
ElasticSerch 的连接查询有两种方式实现 nested parent和child关联查询 nested 存储结构 nested的方式和其他字段一样,在同一个type里面存储,以数组的方式存储 ...
- JDBC MySQL 多表关联查询查询
public static void main(String[] args) throws Exception{ Class.forName("com.mysql.jdbc.Driver&q ...
- MYSQL基础操作之数据约束与关联查询
一.MYSQL约束 1.默认值约束,当字段没有插入值的时候,mysql自动给该字段分配默认值. 默认值的字段允许为空. 对默认值字段也可以插入null. CREATE TABLE STUDENT( I ...
- C#代码中实现两个表(DataTable)的关联查询(JOIN)
之前通常都是使用SQL直接从数据库中取出表1和表2关联查询后的数据,只需要用一个JOIN就可以了,非常方便.近日遇到一种情况,两个表中的数据已经取到代码中,需要在代码中将这两个表关联起来,并得到它们横 ...
- Mybatis关联查询和数据库不一致问题分析与解决
Mybatis关联查询和数据库不一致问题分析与解决 本文的前提是,确定sql语句没有问题,确定在数据库中使用sql和项目中结果不一致. 在使用SpringMVC+Mybatis做多表关联时候,发现也不 ...
- Mysql多表表关联查询 inner Join left join right join
Mysql多表表关联查询 inner Join left join right join
- YII2-数据库数据查询方法,关联查询with, joinWith区别和分页
一.ActiveRecord 活动记录 1.with关联查询 例如,查询评论 $post = Post::find()->with('comments'); 等价于以下结果集 SELECT * ...
- Mybatis高级查询之关联查询
learn from:http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html#Result_Maps 关联查询 准备 关联结果查询(一对一) resul ...
随机推荐
- on-session问题
.D:\0kecheng\bos\bosv2.0_chapter03.无条件查询. 方法1.@JSON(serialize=false)是注解排除不需要加载的实体类上,找到它的get方法,解决no-s ...
- 【洛谷P2447】[SDOI2010]外星千足虫
外星千足虫 题目链接 首先,它一看题解就是个高斯消元 只是改成了奇偶性的判断 性质: 奇数+奇数=偶数 奇数+偶数=奇数 偶数+奇数=奇数 偶数+偶数=偶数 于是我们用1表示奇数,0表示偶数 1+1= ...
- 学大伟业 Day 4 培训总结
今天讲的全是dp... 不多废话,先看一道经典的模板LIS(最长不下降子序列) 一.LIS 给定一个长度为N的数列,求最长上升子序列 例:1 7 2 8 3 4 答案:1 2 3 4 代码: #inc ...
- Python—面向对象01
1.如何使用类 # 先定义类 class LuffyStudent(): school = "luffycity" # 数据属性 def learn(self): # 函数属性 p ...
- Python 学习笔记(七)Python字符串(三)
常用字符串方法 split() 分割字符串,指定分隔符对字符串进行分割 join() 将序列中的元素以指定的字符连接生成一个新的字符串 str.strip() 用于移除字符串头尾指定的字符(默认 ...
- linux各种抓包情况说明
大家都知道抓包指令:tcpdump 抓包的主要目的是测试端口.网络协议通不通,以及对抓取的数据包进行分析.测试,抓包对熟悉linux的大神都不陌生,网络对于我来说也是一窍不通,只是在这里记录一下 ...
- WKWebView进度及title
WKWebView进度及title WKWebView进度及title WKWebView 的estimatedProgress和title 都是KVO模式,所以可以添加监控: [webView ad ...
- NEC 框架规范 css reset
/* reset */html,body,h1,h2,h3,h4,h5,h6,div,dl,dt,dd,ul,ol,li,p,blockquote,pre,hr,figure,table,captio ...
- 使用php+gmail 发送邮件
<?php namespace app\index\controller; use think\Controller; use PHPMailer\PHPMailer; class Test e ...
- centos7编译安装Apache
一.安装 安装之前先将服务器的防火墙关掉. systemctl stop firewalld systemctl disable firewall 第一步: 安装apr 下载: wget -c ...