Elasticsearch 连接查询

在一般的关系型数据库中,都支持连接操作。

在ES这种分布式方案中进行连接操作,代价是十分昂贵的。

不过ES也提供了相类似的操作,支持水平任意扩展,实现连接的效果。

其他内容,参考Elasticsearch官方指南整理

ES中的连接

在ES中支持两种连接方式:嵌套查询 和 has_child、has_parent父子查询

嵌套查询:

文档中包含嵌套的字段,这些字段以数组的形式保存对象,这样每个嵌套的子对象都可以被搜索。

has_child、has_parent父子查询:

父子文档是存储在同一个索引中的不同类型,在索引数据前定义父子关系。在父子查询中,父子关系通过类型引用。

嵌套查询

嵌套类型需要实现定义好mapping:

{
    "type1" : {
        "properties" : {
            "obj1" : {
                "type" : "nested"
            }
        }
    }
}

定义好后,type1中就有了obj1这个子对象,然后就可以通过嵌套查询查询相关的内容:

{
    "nested" : {
        "path" : "obj1",
        "score_mode" : "avg",
        "query" : {
            "bool" : {
                "must" : [
                    {
                        "match" : {"obj1.name" : "blue"}
                    },
                    {
                        "range" : {"obj1.count" : {"gt" : 5}}
                    }
                ]
            }
        }
    }
}

注意其中几个参数:

1 path 定义了嵌套的对象

2 score_mode 定义里嵌套对象计算的分数与当前查询分数的处理方式,有avg,sum,max,min以及none。none就是不做任何处理,其他的看字面意思就好理解。

3 query/filter是查询的方式,内部定义了针对嵌套对象的查询,注意内部的查询一定要是用全路径,即针对obj1的name字段的查询,要写obj1.name。

嵌套查询会在执行子查询的时候自动触发,然后把结果返回给当前文档的查询。

父子查询

父子关系也需要在之前定义mapping,不过与一般的映射不同,它的定义方式如下:

PUT my_index
{
  "mappings": {
    "my_parent": {},
    "my_child": {
      "_parent": {
        "type": "my_parent"
      }
    }
  }
}

PUT my_index/my_parent/1
{
  "text": "This is a parent document"
}

PUT my_index/my_child/2?parent=1
{
  "text": "This is a child document"
}

PUT my_index/my_child/3?parent=1
{
  "text": "This is another child document"
}

GET my_index/my_parent/_search
{
  "query": {
    "has_child": {
      "type": "my_child",
      "query": {
        "match": {
          "text": "child document"
        }
      }
    }
  }
}

这样就代表,my_child这个类型的父类型是my_parent,这样就声明了一种父子关系。然后再索引数据时,指定父子对应的关系。

has_child查询

这个查询会检查子文档,如果子文档满足查询条件,则返回父文当。

{
    "has_child" : {
        "type" : "blog_tag",
        "query" : {
            "term" : {
                "tag" : "something"
            }
        }
    }
}

通过score_mode字段,可以指定子文档返回的分值的处理方式。与嵌套类似,它也有avg,sum,max,min和none几种方式。

{
    "has_child" : {
        "type" : "blog_tag",
        "score_mode" : "sum",
        "query" : {
            "term" : {
                "tag" : "something"
            }
        }
    }
}

另外,也可以指定子文档匹配的最小数目和最大数目。

{
    "has_child" : {
        "type" : "blog_tag",
        "score_mode" : "sum",
        "min_children": 2,
        "max_children": 10,
        "query" : {
            "term" : {
                "tag" : "something"
            }
        }
    }
}

has_parent查询

has_parent查询与has_child类似,它是去检查父文档那个是否匹配,然后返回父文档对应的子文档。

{
    "has_parent" : {
        "parent_type" : "blog",
        "query" : {
            "term" : {
                "tag" : "something"
            }
        }
    }
}

参考

1 如何定义父子关系:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-parent-field.html

2 连接查询:https://www.elastic.co/guide/en/elasticsearch/reference/current/joining-queries.html

3 Nested查询:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html

4 Has_Child查询:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-has-child-query.html

5 Has_Parent查询:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-has-parent-query.html

时间: 2024-08-09 06:34:36

Elasticsearch 连接查询的相关文章

elasticsearch 连接查询 基于es5.1.1

ElasticSerch 的连接查询有两种方式实现 nested parent和child关联查询 nested 存储结构 nested的方式和其他字段一样,在同一个type里面存储,以数组的方式存储在 type里,格式如下: PUT index_test/type_info/1000 { "userId": 1000, "mobile": "13301020202", "nick": "梅西", &quo

Oracle 连接查询<一>

在Oracle数据库中,连接查询分为交叉连接.内连接.外链接3种类型.其中,交叉连接结果是所有其他连接结果的超集,而外连接结果又是内连接结果的超集. 交叉连接 交叉连接又称为笛卡尔积连接,是两个或多个 表之间的无条件连接.一个表中所有记录分别与其他表中所有记录进行记录.如果进行连接的表分别有n1,n2,n3...条记录,那么交叉连接的结果集中将有n1 x n2 x n3 x...条记录.例如,emp表中有14条记录,dept表中有4条记录,那么两个交叉连接后有56条记录,语句为 SQL> SEL

表连接查询与where后使用子查询的性能分析。

子查询就是在一条查询语句中还有其它的查询语句,主查询得到的结果依赖于子查询的结果. 子查询的子语句可以在一条sql语句的FROM,JOIN,和WHERE后面,本文主要针对在WHERE后面使用子查询与表连接查询的性能做出一点分析. 对于表连接查询和子查询性能的讨论众说纷纭,普遍认为的是表连接查询的性能要高于子查询.本文将从实验的角度,对这两种查询的性能做出验证,并就实验结果分析两种查询手段的执行流程对性能的影响. 首先准备两张表 1,访问日志表mm_log有150829条记录(相关sql文件已放在

Mysql 表连接查询

1.内联接(典型的联接运算,使用像 =  或 <> 之类的比较运算符).包括相等联接和自然联接.     内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行.例如,检索 students和courses表中学生标识号相同的所有行.       2.外联接.外联接可以是左向外联接.右向外联接或完整外部联接.     在 FROM子句中指定外联接时,可以由下列几组关键字中的一组指定:     1)LEFT  JOIN或LEFT OUTER JOIN     左向外联接的结果集包括  LEF

MySQL数据库实验三:连接查询

实验三    连接查询 实验名称:连接查询(2课时) 一.实验目的 理解JOIN语句的操作和基本使用方法,掌握内连接.外连接.自身连接的概念和使用. 二.实验环境 是MS SQL SERVER 2005的中文客户端. 三.实验示例 1. 查询每个学生及其选修课程的情况 SELECT  Student.*,SC.* FROM     Student,SC WHERE  Student.Sno = SC.Sno: 2.检索至少选修课程号为C2和C4的学生学号 SELECT X.S# FROM SC

7-09内连接查询

多表连接查询:实际上是通过各个表之间共同列的关联行来查询数据的,它是关系数据库查询最主要的特征. 连接查询的分类: 内连接:根据表中共同的列进行匹配. 内连接的特点: 两个表存在主外键关系 参与查询两个表的地位相同无主次之分. 内连接查询就是两个表的数据放到一起相同的数据就是内连接查询. 内连接的实现方式: 1:使用WHERE语句指定连接条件. 2:在FROM语句中使用INNER JOIN..ON. 查询订单编号,还有商品编号: SELECT OrderInfo.OrderId,UserInfo

连接查询,结构、循环语句

1 连接查询:通过连接运算符可以实现多个表查询.1.1 join onselect name,mark from student join mark on student.id=mark.studentid左连接-left joinselect name,mark from student left join mark on student.id=mark.studentid右连接-right joinselect name,mark from student right join mark o

20150103--SQL连接查询+视图-01

回顾 列属性:注释和唯一键 关系:一对一,多对一,多对多 范式:规范数据表设计的方式 外键:外键约束(严格,置空,级联) 高级数据操作:增删改查 查询操作 完整语法 select select选项 表达式 from子句 where子句 group by子句 having子句 order by子句 limit子句 group by分组 分组语法 group by就是根据某个条件对数据进行分组. 语法:group by 字段 分组之后,会对数据进行取第一条. 分组主要是用来进行数据统计. 统计函数

连接查询

连接查询:列的扩展1. 等值连接查询 (内连接) 笛卡尔积 join on 2. 外连接(left.right.full) left左连接: left 左边表为主表 ,右边的为从表,显示的结果集以主表为主 如果从表中没有和它匹配的数据,就以NULL值填充 right右连接: right 右边的表为主表 full 全连接 每个表都完全显示,互相匹配数据,如果对方没有则以NULL填充 联合查询:行的扩展 用Union将两个查询联合起来显示,追加行的形式在结果集中显示 必须保证两个查询结果的列的格式是