有没有办法在 Elastisearch 中创建嵌套对象的分页? 我在下面的示例数据中搜索办公室(嵌套对象)并且只需要为请求的分页页面加载嵌套匹配项。 例如,对于
page 3
,我需要从偏移量8(office.3D、office.3E、office.4A、office.4B)加载4个项目+匹配嵌套项目的总数。
|-company.1
| |-name
| |-address
| |-offices __ __
| |-office.1A |
|-company.2 |
| |-name |
| |-address | page 1, size=4, offset=0
| |-offices |
| |-office.2A |
| |-office.2B |
| |-office.2C __|__
|-company.3 |
| |-name |
| |-address |
| |-offices | page 2, size=4, offset=4
| |-office.3A |
| |-office.3B |
| |-office.3C |
| |-office.3D __|__
| |-office.3E |
|-company.4 |
| |-name |
| |-address | page 3, size=4, offset=8
| |-offices |
| |-office.4A |
| |-office.4B |
| |-office.4C __|__
|-company.5
...
映射:
{
"mappings": {
"properties": {
"name": { "type" : "keyword" }
"address": { "type" : "keyword" }
"offices": {
"type": "nested",
"properties": {
"hash": { "type": "keyword" },
"street": { "type": "keyword" },
"city": { "type": "keyword" },
"zip": { "type": "keyword" },
}
}
}
}
}
问题是,加载
page 2
(偏移量=4)应该在上面的示例中加载根文档company.3
。
但是Elasticsearch似乎不支持嵌套字段的偏移量,仅支持父文档,或者inner_hits
.的嵌套对象内
我尝试了很多查询和聚合,但目前唯一可行的解决方案是加载所有匹配的嵌套对象以及根/父文档并循环遍历所有对象,直到我达到嵌套字段的偏移量
0... nested offset
。
然而,这是非常低效的,即使只允许最多 500 页(每页大小 20 个项目,意味着 10.000 个默认 ES 限制)我仍然可能达到内存限制。
数据库有多达 200 万。根文档的记录,以及 600k 嵌套的 office 记录。
目前我使用以下查询 - 例如:
{
query: {
bool: {
must: {
0: {
nested: {
path: office
inner_hits: { size: 20 }
query: {
bool: {
must: {
0: {
wildcard: {
office.city: Bratislava*
}
}}}}}}}}}
aggregations: {
cnt-total: {
nested: {
path: office
aggs: {
cnt-matching: {
filter: {
bool: {
must: {
0: {
wildcard: {
office.city: Bratislava*
}
}}}}}}}}}
}
这将给我正确的匹配嵌套文档总数。 但是我必须遍历所有加载的父文档并通过脚本计算嵌套偏移量。 有没有更有效的方法来做到这一点?