ElasticSearch join连接查询

ElasticSearch join连接查询

特别说明:文章所有内容基于ElasticSerch 5.5.3版本

ElasticSerch 的连接查询有两种方式实现

  • nested
  • parent和child关联查询

nested

  • 存储结构
    nested的方式和其他字段一样,在同一个type里面存储,以数组的方式存储在
    type里,格式如下:
PUT index_test/type_info/1000
{
  "userId": 1000,
  "mobile": "13301020202",
  "nick": "梅西",
  "vipType": 1,
  "vipPoints": 1200,
  "regTime": "2018-06-18 12:00:31",
  "order": [
    {
      "status": 1,
      "payMethod": 2,
      "amount": 100,
      "productCount": 3
    },
    {
      "status": 2,
      "payMethod": 2,
      "amount": 230,
      "productCount": 1
    }
  ]
}

order 则为 nested

  • API查询方式
    直接用.连接对象的属性,如要要查找订单中状态=2的用户,直接使用order.status
GET index_test/type_info/_search
{
  "query": {
    "term": {
      "order.status": 2
    }
  }
}

parent / child 关联的方式

  • 存储结构
    parent / child 的存储结果跟nested不一样,是存储在不同的type里,通过parent来关联父子type关系
PUT index_test
{
 "mappings": {
   "type_info": {
     "properties": {
       "userId": {
         "type": "integer"
       },
       "mobile": {
         "type": "keyword"
       },
       "nick": {
         "type": "keyword"
       },
       "vipType": {
         "type": "integer"
       },
       "vipPoints": {
         "type": "integer"
       },
       "regTime": {
         "type": "date",
         "format": "yyyy-MM-dd HH:mm:ss"
       }
     }
   },
   "type_order": {
     "_parent": {
       "type": "type_info"
     },
     "properties": {
       "amount": {
         "type": "scaled_float",
         "scaling_factor": 100
       },
       "payMethod": {
         "type": "integer"
       },
       "status": {
         "type": "integer"
       },
       "productCount": {
         "type": "integer"
       }
     }
   }
 }
}

通过 _parent 来指定父type

  • 造点数据
    添加几条用户数据,和普通的type一样,没有任何区别
PUT index_test/type_info/1000
{
 "userId": 1000,
 "mobile": "13301020202",
 "nick": "梅西",
 "vipType": 1,
 "vipPoints": 1200,
 "regTime": "2018-06-18 12:00:31"
}
PUT index_test/type_info/1001
{
 "userId": 1001,
 "mobile": "151232223",
 "nick": "C罗",
 "vipType": 1,
 "vipPoints": 300,
 "regTime": "2018-05-18 12:00:00"
}
PUT index_test/type_info/1002
{
 "userId": 1002,
 "mobile": "181829282",
 "nick": "内马尔",
 "vipType": 2,
 "vipPoints": 1300,
 "regTime": "2018-09-09 12:00:00"
}

添加几条订单数据,通过parent来指定type_info

PUT index_test/type_order/100?parent=1000
{
"userId": 1000,
"amount": 300,
"payMethod": 2,
"status": 3,
"productCount": 2
}
```javascript

PUT index_test/type_order/101?parent=1000
{
“userId”: 1000,
“amount”: 250,
“payMethod”: 1,
“status”: 2,
“productCount”: 1
}

  ```javascript
PUT index_test/type_order/102?parent=1001
{
"userId": 1001,
"amount": 56,
"payMethod": 1,
"status": 2,
"productCount": 1
}
```javascript

PUT index_test/type_order/103?parent=1002
{
“userId”: 1002,
“amount”: 78,
“payMethod”: 2,
“status”: 1,
“productCount”: 2
}

- API查询方式
- 通过子type查询父type,返回父type信息
查询下单金额大于60的用户,通过 `has_child` 查询,返回用户信息

GET index_test/type_info/_search
{
“query”: {
“has_child”: {
“type”: “type_order”,
“query”: {
“range”: {
“amount”: {
“gte”: 60
}
}
}
}
}
}

 - 通过父type查子type,返回子type信息
查询vip等级为1的用户下的订单,通过 `has_parent` 查询,返回订单信息
```javascript
GET index_test/type_order/_search
{
 "query": {
   "has_parent": {
     "parent_type": "type_info",
     "query": {
       "term": {
         "vipType": {
           "value": 1
         }
       }
     }
   }
 }
}

nested 和 parent-child的区别以及使用场景

  • 主要区别:
    由于存储结构的不同,nested和parent-child的方式有不同的应用场景
    nested 所有实体存储在同一个文档,parent-child模式,子type和父type存储在不同的文档里。
    所以查询效率上nested要高于parent-child,但是更新的时候nested模式下,es会删除整个文档再创建,而parent-child只会删除你更新的文档在重新创建,不影响其他文档。所以更新效率上parent-child要高于nested。

  • 使用场景:
    nested:在少量子文档,并且不会经常改变的情况下使用。
    比如:订单里面的产品,一个订单不可能会有成千上万个不同的产品,一般不会很多,并且一旦下单后,下单的产品是不可更新的。
    parent-child:在大量文档,并且会经常发生改变的情况下使用。
    比如:用户的浏览记录,浏览记录会很大,并且会频繁更新

  • 15
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
在Java中实现ESElasticsearch)的left join关联查询,可以通过以下步骤进行: 1. 首先,你需要使用Java的Elasticsearch客户端库来连接和操作Elasticsearch。常用的Java Elasticsearch客户端库有Elasticsearch Java High Level REST Client和Elasticsearch Java Transport Client。 2. 创建一个Elasticsearch查询请求,使用`SearchRequest`对象来定义查询的索引、类型和查询条件等信息。 3. 使用`SearchSourceBuilder`对象来构建查询的DSL(Domain Specific Language),包括设置查询条件、过滤条件、排序等。 4. 对于left join关联查询,你可以使用Elasticsearch的`Nested`或`Parent-Child`关系来实现。如果你的数据模型中存在嵌套字段,可以使用`Nested`关系来进行关联查询。如果你的数据模型中存在父子关系,可以使用`Parent-Child`关系来进行关联查询。 5. 在查询DSL中,使用`Nested Query`或`Has Parent Query`来进行关联查询。你可以通过设置`path`参数指定嵌套字段的路径或者指定父文档的类型。 6. 执行查询请求,获取查询结果。使用Elasticsearch客户端库提供的方法来发送查询请求并解析返回的结果。 下面是一个示例代码片段,演示了如何使用Java Elasticsearch High Level REST Client实现ES的left join关联查询: ```java // 创建Elasticsearch客户端 RestHighLevelClient client = new RestHighLevelClient( RestClient.builder(new HttpHost("localhost", 9200, "http"))); // 创建查询请求 SearchRequest searchRequest = new SearchRequest("index_name"); searchRequest.types("type_name"); // 构建查询DSL SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); sourceBuilder.query(QueryBuilders.nestedQuery("nested_field", QueryBuilders.matchQuery("nested_field.field_name", "query_value"), ScoreMode.None)); // 设置查询DSL searchRequest.source(sourceBuilder); // 执行查询请求 SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); // 解析查询结果 SearchHits hits = searchResponse.getHits(); for (SearchHit hit : hits) { // 处理每个文档的结果 Map<String, Object> sourceAsMap = hit.getSourceAsMap(); // ... } // 关闭Elasticsearch客户端 client.close(); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五只鸭子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值