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

本文转自博客园xingoo的博客,原文链接:Elasticsearch 连接查询,如需转载请自行联系原博主。

时间: 2024-10-14 13:34:18

Elasticsearch 连接查询的相关文章

SQL连接查询1 内联接查询

在数据库开发方面,通过单表所表现的实现,有时候需要组合查询来找到我们需要的记录集,这时候我们就会用到连接查询. 连接查询主要包括以下几个方面: 内连接 内连接一般是我们最常使用的,也叫自然连接,是用比较运算符比较要联接列的值的联接.它是通过(INNER JOIN或者JOIN)关键字把多表进行连接.我们通过建立两个表来说明问题: StudentID StudentName StudentAge----------- -----------------------------------------

一种嵌套查询,变成连接查询的办法

主 题:这句sql语句可不可以变成连接查询的呢? 作 者:overmind (overmind) 等 级: 信 誉 值:100 所属社区:Oracle 开发 问题点数:100 回复次数:6 发表时间:2004-12-14 10:31:43 select t1.oid from t1 where t1.oid not in (select oid from t2 where t2.userid='overmind'); 回复人: overmind(overmind) ( ) 信誉:100 2004

数据库中的连接查询

   数据库中的各个表中存放着不同的数据,用户往往需要用多个表中的数据来组合.提炼出所需要的信息.如果一个查询需要对多个表进行操作,就称为连接查询.连接查询的结果集或结果表,称为表之间的连接连接.查询实际上是通过各个表之间共同列的关联性来查询数据的,它是关系数据库查询最主要的特征.连接查询分为等值连接查询.非等值连接查询.自连接查询.外部连接查询和复合条件连接查询. 10.3.1 等值与非等值连接查询表之间的连接是通过相等的字段值连接起来的查询称为等值连接查询.可以用两种方式来指定连接条件.下面

MS SQL基础教程:数据库中的连接查询

数据库中的各个表中存放着不同的数据,用户往往需要用多个表中的数据来组合.提炼出所需要的信息.如果一个查询需要对多个表进行操作,就称为连接查询.连接查询的结果集或结果表,称为表之间的连接连接.查询实际上是通过各个表之间共同列的关联性来查询数据的,它是关系数据库查询最主要的特征. 连接查询分为等值连接查询.非等值连接查询.自连接查询.外部连接查询和复合条件连接查询. 10.3.1 等值与非等值连接查询 表之间的连接是通过相等的字段值连接起来的查询称为等值连接查询.可以用两种方式来指定连接条件.下面例

SQL 连接查询语法及使用

  一.交叉连接(cross join) 交叉连接(cross join):有两种,显式的和隐式的,不带on子句,返回的是两表的乘积,也叫笛卡尔积. 例如:下面的语句1和语句2的结果是相同的. 语句1:隐式的交叉连接,没有cross join. select o.id, o.order_number, c.id, c.name from orders o , customers c where o.id=1; 语句2:显式的交叉连接,使用cross join. select o.id,o.ord

StreamRead和sqlparamter,sql连接查询

  StreamRead和sqlparamter,sql连接查询以及分页整理 -> Xml操作 InnerText 会对标签<>转义 InnerXml 不会对标签转义 委托 多播委托. --写入txt StreamWrite 写入文本 reader.FieldCount得到字段的个数 StreamWrite对象的WriteLine()方法就可以把读取的内容写入到txt中 StreamRead 读取文本 string temp; while((temp = reader.ReadLine(

mysql-MySQL内连接查询结果的显示顺序

问题描述 MySQL内连接查询结果的显示顺序 表fruits的字段f_id为primary key 表suppliers的字段s_id为primary key与fruits的s_id有相同的数据类型 然后使用这句查询语句: 1.select suppliers.s_id,s_name,f_name,f_price from suppliers inner join fruits on suppliers.s_id=fruits.s_id; 查询的都结果显示如下: 2.变换表的位置再查询: sel

android使用ormLite,多表连接查询

问题描述 android使用ormLite,多表连接查询 解决方案

mysql-关于MySQL的完全外连接查询

问题描述 关于MySQL的完全外连接查询 问题看下图 为毛左连接和右连接查询都可以,全外连接就不行了啊?而且命令我也是直接翻阅上面的,只是把right改成了full 解决方案 mysql 不支持full joinhttp://blog.csdn.net/whitebill2004/article/details/7570541 解决方案二: (A left join B ) union (A right join B) 解决方案三: select [列名称] from 表名称 cross joi