elasticsearch 连接查询 基于es5.1.1

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"
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
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
}
PUT index_test/type_order/101?parent=1000
{
"userId": 1000,
"amount": 250,
"payMethod": 1,
"status": 2,
"productCount": 1
}
PUT index_test/type_order/102?parent=1001
{
"userId": 1001,
"amount": 56,
"payMethod": 1,
"status": 2,
"productCount": 1
}
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 查询,返回订单信息
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:在大量文档,并且会经常发生改变的情况下使用。 
    比如:用户的浏览记录,浏览记录会很大,并且会频繁更新

原文地址:https://www.cnblogs.com/chenmz1995/p/11261655.html

时间: 2024-10-17 05:28:14

elasticsearch 连接查询 基于es5.1.1的相关文章

Elasticsearch 连接查询

在一般的关系型数据库中,都支持连接操作. 在ES这种分布式方案中进行连接操作,代价是十分昂贵的. 不过ES也提供了相类似的操作,支持水平任意扩展,实现连接的效果. 其他内容,参考Elasticsearch官方指南整理 ES中的连接 在ES中支持两种连接方式:嵌套查询 和 has_child.has_parent父子查询 嵌套查询: 文档中包含嵌套的字段,这些字段以数组的形式保存对象,这样每个嵌套的子对象都可以被搜索. has_child.has_parent父子查询: 父子文档是存储在同一个索引

基于百度地图SDK和Elasticsearch GEO查询的地理围栏分析系统(1)

本文描述了一个系统,功能是评价和抽象地理围栏(Geo-fencing),以及监控和分析核心地理围栏中业务的表现. 技术栈:Spring-JQuery-百度地图WEB SDK 存储:Hive-Elasticsearch-MySQL-Redis 什么是地理围栏? LBS系统中,地理围栏指的是虚拟边界围成的部分. tips:这只是一个demo,支撑实习生的本科毕设,不代表生产环境,而且数据已经做了脱密处理,为了安全还是隐去了所有数据. 功能描述 1.地理围栏的圈选 (1)热力图 热力图展示的是,北京市

连接查询时on与where的区别

写在前面:在编写SQL的过程中,我经常使用LEFT JOIN关联多个小查询形成一个大查询,产生一张宽表.在进行这些查询中,给我感触最深的亮点是:1.left join中主表的选择,主表的选择很重要,否则就会漏掉一些记录或者ID:2.连接查询的ON条件和外层的WHERE条件的区分使用,如果对他们的作用以及区别有一个很清晰的认识,那么用混一条语句就可能产生很大的差别.因此,本文在学习了网友的博文的基础上进行如下总结和整理. 关键点:数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,

高级数据操作--连接查询

一.连接查询——交叉连接 概念 表与表之间是有联系的! 所谓的连接查询,就是指将两张表或者多张表按照某个指定的条件,进行横向上的连接并显示! 所以,从结果上看,字段数增加了! 分类 根据连接查询的性质不同,又可以分成交叉连接.内连接.外连接和自然连接! 交叉连接关键字:cross join  交叉连接含义: 交叉连接是最容易理解的,就是指从一张表中的每一条记录分别去连接另外一张表的所有的记录,并且保存所有的记录,其中也包括两张表的所有的字段! 所以说,交叉连接的本质就是两张数据表做笛卡尔积! 笛

oracle中的连接查询总结

连接查询: 连接查询是指基于多张表或视图的查询.使用连接查询时,应指定有效的查询条件,不然可能会导致生成笛卡尔积.如现有部门表dept,员工表emp,以下查询因查询条件无效,而产生笛卡尔积:   (各语句中字段不做解释,主要显示逻辑关系) select dept.dname,emp.ename from dept,emp where dept.name = 'sales'; 有效查询条件应该指定dept表与emp表之间的连接关系.表之间连接关系多如下: 1.相等连接(=) 相等连接主要用于查询主

数据库的子查询、连接查询

新建两个表,teacher student create table teacher ( id int primary key auto_increment, name varchar(20)  not null default 't' )engine innodb character set utf8; create table student ( id int primary key auto_increment, name varchar(20) not null default 't',

oracle(sql)基础篇系列(二)——多表连接查询、子查询、视图

    多表连接查询 内连接(inner join) 目的:将多张表中能通过链接谓词或者链接运算符连接起来的数据查询出来. 等值连接(join...on(...=...)) --选出雇员的名字和雇员所在的部门名字 --(1)必须明确的指出重复字段属于哪个表 select ename,dname dept.deptno from emp,dept where emp.deptno = dept.deptno;   --(2)新语法:join...on(...=...) select ename,

单表查询、多表查询、虚拟表连接查询

  单表查询,以下面这个表为例:+----+------------+--------+-----+------------+----------------------------+--------------+------------+--------+-----------+| id | name | sex | age | hire_date | post | post_comment | salary | office | depart_id |+----+------------+-

elasticsearch常用查询

query DSL match 查询 { "match": { "tweet": "About Search" } } 注:match查询只能就指定某个确切字段某个确切的值进行搜索,做精确匹配搜索时, 你最好用过滤语句,因为过滤语句可以缓存数据. match_phrase 查询 { "query": { "match_phrase": { "title": "quick bro