使用汇总结果过滤另一个索引中的文档

法比恩·汉农(Fabien Henon)

我有2个索引:

  • users
  • navigations

假设users看起来像这样:

{
  "properties": {
    "cookies": {"type": "keyword"},
    "name": {"type": "text"}
  }
}

而且navigations是这样的:

{
  "properties": {
    "url": {"type": "keyword"},
    "cookie_id": {"type": "keyword"}
  }
}

如您所见,users并且navigations可以通过cookie_idcookies字段连接在一起

实际上,我的索引有更多字段,但是只有这些字段才可以证明我的问题。

我存储usersnavigations在2个不同的指标,而不是使用join映射或nested映射,因为我有更多的navigations不是用户,并在我的大部分搜索使用情况下,我会只搜索users,所以我不想保持列表navigations每个users我更喜欢将它们分开(我还有其他一些约束,促使我选择2个单独的索引,例如数据协调等)。

我想做的是这样的查询/汇总:“给我所有在name Fabien那浏览了5次的用户url http://example.com

到目前为止,我进行了以下查询/汇总(搜索查询是在我的2个索引上完成的):

POST /用户,导航/ _搜索

{
  "query": {
    "bool": {
      "must": [
        {"match": {"name": "Fabien"}}
      ]
    }
  },
  "aggregations": {
    "all_navs": {
        "global": {},
        "aggregations": {
            "cookies": {
                "terms": {"field": "cookie_id"},
                "aggregations": {
                    "page_visited": {
                        "filter": {
                            "bool": {
                                "must": [
                                    {"term": {"url": "http://example.com"} }
                                ]
                            }                           
                        },
                        "aggregations": {
                            "number_page_visited": {
                                "value_count": {"field": "type"}
                            }
                        }
                    },
                    "count_filter": {
                        "bucket_selector": {
                            "buckets_path": {
                                "count": "page_visited>number_page_visited"
                            },
                            "script": "params.count > 5"
                        }
                    }
                }
            }
        }
    }
  }
}

通过这个查询,我可以用过滤我usersname = Fabien,并且我可以cookie_idnavigations至少有5个文档的地方获取url = http://example.com

但是我不知道如何使用cookie_id聚合中s过滤我的users

任何想法?

谢谢!

皮埃尔·尼古拉斯·穆格尔

具有两个单独索引的解决方案

由于elasticsearch不是关系数据库,因此您将无法在单个请求中检索结果。这是Elasticsearch的强大局限性,但也是其出色表现的主要原因。

基本上,elasticsearch会将您的查询编译为Lucene查询,并使用Lucene查询执行索引扫描。没有一种机制可以使查询中的某些参数(例如,user_id字段的值)依赖于另一个查询的结果(例如,idusers名称为“ Fabien”的地方查找所有)。

您将必须在外部执行连接:

  • 首先,从users名称为的索引检索所有文档Fabien如果文档数量不受限制,则必须执行滚动搜索或使用search_after

  • 第二,从索引navigation检索所有文件,这些索引user_id位于第一个请求返回的文档集中的位置,并且满足您的其他条件。

这种方法可能很慢,并且不能保证在运行第二个查询时用户索引尚未更新。

连接映射解决方案

实际上,如果您使用联接类型映射,则无需在用例中使用聚合。

请注意,join字段有几个限制,不建议将其作为对一对多关系建模的默认解决方案。

这是一个可以满足您的要求的工作示例。

映射:包含用户和导航字段以及一个连接字段。

PUT /user_navigation
{
    "mappings": {
        "properties": {
            "cookies": {
                "type": "keyword"
            },
            "name": {
                "type": "keyword"
            },
            "join_field": {
                "type": "join",
                "relations": {
                    "user": "navigation"
                }

            }
        }
    }
}

添加一些测试文档。两个父文档有个,name: Fabien但只有一个有两个孩子cookies: http://example.com另一个文档有两个子对象,cookies: http://example.com但没有以命名Fabien

POST user_navigation/_doc/_bulk
{ "index" : { "_index" : "user_navigation", "_id" : "1" } }
{ "name" : "Fabien", "join_field": "user" }
{ "index" : { "_index" : "user_navigation", "_id" : "2" } }
{ "name" : "Fabien", "join_field": "user" }
{ "index" : { "_index" : "user_navigation", "_id" : "3" } }
{ "name" : "Autre", "join_field": "user" }
{ "index" : { "_index" : "user_navigation", "routing": "1" } }
{ "cookies": "http://example.com", "join_field": { "name": "navigation",  "parent": "1"  }}
{ "index" : { "_index" : "user_navigation", "routing": "1"} }
{ "cookies": "http://example.com", "join_field": { "name": "navigation",  "parent": "1"  }}
{ "index" : { "_index" : "user_navigation", "routing": "2"} }
{ "cookies": "http://example.com", "join_field": { "name": "navigation",  "parent": "2"  }}
{ "index" : { "_index" : "user_navigation", "routing": "2"} }
{ "cookies": "other_url", "join_field": { "name": "navigation",  "parent": "3"  }}
{ "index" : { "_index" : "user_navigation", "routing": "3"} }
{ "cookies": "http://example.com", "join_field": { "name": "navigation",  "parent": "3"  }}
{ "index" : { "_index" : "user_navigation", "routing": "3"} }
{ "cookies": "http://example.com", "join_field": { "name": "navigation",  "parent": "3"  }}

以下请求使用has_child查询,并将仅返回带有name: Fabien的文档,这样它至少具有两个带有的子文档cookies: http://example.com

GET user_navigation/_doc/_search
{
    "query": {
        "bool": {
            "must": [
                {
                    "term": {
                        "name": "Fabien"
                    }
                },
                {
                    "has_child": {
                        "type": "navigation",
                        "query": {
                            "term": {
                                "cookies": "http://example.com"
                            }
                        },
                        "min_children": 2,
                        "inner_hits": {}
                    }
                }
            ]
        }
    }
}

响应将仅包含ID为1的文档。

"min_children" 参数允许更改必须满足请求的子文档的最小数量。

"inner_hits": {} 允许在响应中检索子文档。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

NodeJ:使用另一个集合的结果过滤mongo查询结果

来自分类Dev

使用JMESPath根据另一个查询结果过滤列表

来自分类Dev

通过另一个变量的结果过滤结果?

来自分类Dev

ElasticSearch按汇总结果过滤

来自分类Dev

Python:使用另一个列表的索引汇总列表中的数据

来自分类Dev

Python:使用另一个列表的索引汇总列表中的数据

来自分类Dev

根据另一个列表中的索引汇总一个列表中的元素

来自分类Dev

使用另一个集合中的属性在mongodb上过滤文档的更好方法

来自分类Dev

使用汇总检索查询结果中术语的文档频率

来自分类Dev

使用汇总检索查询结果中术语的文档频率

来自分类Dev

使用索引位置通过另一个数组中的值过滤数组-javascript

来自分类Dev

如何在mongodb中的另一个文档中过滤文档的字段?

来自分类Dev

使用linq从另一个列表获取的索引值过滤一个列表

来自分类Dev

如何使用汇总来计算文档并总结特定字段?

来自分类Dev

从另一个文件调用汇编函数

来自分类Dev

如果另一个表中存在值,则过滤表的索引列表

来自分类Dev

使用索引数组过滤另一个数组

来自分类Dev

Python使用另一个列表中的元素过滤出一个列表

来自分类Dev

使用Knitr将Markdown文档的部分插入另一个Markdown文档中

来自分类Dev

使用Matlab将Word文档的样式复制到另一个文档中

来自分类Dev

如何使用每周汇总的另一个表中的值创建临时表?

来自分类Dev

过滤汇总结果

来自分类Dev

从另一个列表创建一个列表,并按某些索引过滤

来自分类Dev

如何使用一个数据框的索引重新索引熊猫中的另一个

来自分类Dev

MongoDB为另一个集合中的每个文档插入一个文档

来自分类Dev

Firestore(Angularfire)“合并”或在另一个文档中引用一个文档

来自分类Dev

获取一个keras模型以输出结果,并使用权重中的另一个来输出结果

来自分类Dev

AvalonDock:如何使用 ILayoutUpdateStrategy 在另一个文档旁边添加一个文档

来自分类Dev

通过另一个矩阵中的值汇总一个矩阵

Related 相关文章

  1. 1

    NodeJ:使用另一个集合的结果过滤mongo查询结果

  2. 2

    使用JMESPath根据另一个查询结果过滤列表

  3. 3

    通过另一个变量的结果过滤结果?

  4. 4

    ElasticSearch按汇总结果过滤

  5. 5

    Python:使用另一个列表的索引汇总列表中的数据

  6. 6

    Python:使用另一个列表的索引汇总列表中的数据

  7. 7

    根据另一个列表中的索引汇总一个列表中的元素

  8. 8

    使用另一个集合中的属性在mongodb上过滤文档的更好方法

  9. 9

    使用汇总检索查询结果中术语的文档频率

  10. 10

    使用汇总检索查询结果中术语的文档频率

  11. 11

    使用索引位置通过另一个数组中的值过滤数组-javascript

  12. 12

    如何在mongodb中的另一个文档中过滤文档的字段?

  13. 13

    使用linq从另一个列表获取的索引值过滤一个列表

  14. 14

    如何使用汇总来计算文档并总结特定字段?

  15. 15

    从另一个文件调用汇编函数

  16. 16

    如果另一个表中存在值,则过滤表的索引列表

  17. 17

    使用索引数组过滤另一个数组

  18. 18

    Python使用另一个列表中的元素过滤出一个列表

  19. 19

    使用Knitr将Markdown文档的部分插入另一个Markdown文档中

  20. 20

    使用Matlab将Word文档的样式复制到另一个文档中

  21. 21

    如何使用每周汇总的另一个表中的值创建临时表?

  22. 22

    过滤汇总结果

  23. 23

    从另一个列表创建一个列表,并按某些索引过滤

  24. 24

    如何使用一个数据框的索引重新索引熊猫中的另一个

  25. 25

    MongoDB为另一个集合中的每个文档插入一个文档

  26. 26

    Firestore(Angularfire)“合并”或在另一个文档中引用一个文档

  27. 27

    获取一个keras模型以输出结果,并使用权重中的另一个来输出结果

  28. 28

    AvalonDock:如何使用 ILayoutUpdateStrategy 在另一个文档旁边添加一个文档

  29. 29

    通过另一个矩阵中的值汇总一个矩阵

热门标签

归档