es的连接查询

标签: es | 发表时间:2016-10-13 16:43 | 作者:weitao1026
出处:http://www.iteye.com

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

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

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

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

http://www.cnblogs.com/xing901022/p/4704319.html

 

 

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

 



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [es] 推荐:

es的连接查询

- - 行业应用 - ITeye博客
在一般的关系型数据库中,都支持连接操作. 在ES这种分布式方案中进行连接操作,代价是十分昂贵的. 不过ES也提供了相类似的操作,支持水平任意扩展,实现连接的效果. 其他内容, 参考Elasticsearch官方指南整理. 在ES中支持两种连接方式:嵌套查询 和 has_child、has_parent父子查询.

MySQL InnoDB 與 PostgreSQL 的 Partial Index(es) 是不一樣的東西…

- - Gea-Suan Lin's BLOG
MySQL InnoDB 指的 Partial Index 是:. An index that represents only part of a column value, typically the first N characters (the prefix) of a long VARCHAR value..

索引表和ES的一点点思考 - CSDN博客

- -
在电商项目中,物理库存系统是个极其重要的系统,订单支付后,就会开始来占用物理库存. 一般情况下,库存系统都是要分库的,因为主要的操作是写操作,例如占用/释放/取消等写操作. 使用分库可以降低数据库写的压力. 尽管写操作为主,但是读操作也是有的. 比如说,库存占用的时候,得先查询是否有库存,而这个查询操作并不都会带上分库因子(用于路由到具体的某个数据库),而是一些比较宽松的查询条件,这些查询条件对应的数据可能分布在不同的数据库上.