【问题标题】:Trino/presto with elastic : how to search nested objects?Trino/presto with elastic:如何搜索嵌套对象?
【发布时间】:2021-08-12 11:28:24
【问题描述】:

我是 trino 的新手,我正在尝试使用它来查询弹性搜索中的嵌套对象。

这是我在 elasticsearch 中的映射:

{
"product_index": {
   "mappings": {
      "properties" :{
          "id" : { "type" : "keyword"},
          "name" { "type" : "keyword"},
          "linked_products" :{
               "type": "nested",
               "properties" :{
                   "id" : { "type" : "keyword"}
                }
           }
        }
      }
    }
}

我需要对 linked_products 下的 id 字段进行查询。 trino 中对 id 字段执行查询的语法是什么? 我是否需要在 elastic 中的目标索引映射上使用特殊定义来映射 trino 的嵌套部分?

================================================ ==========

嗨, 我将尝试对我的问题进行一些澄清。

我们正在尝试根据 id 字段查询数据。 这是 Elastic 中的查询:

get product_index/_search
{ 
"query": {
"nested" : {
"path" : "linked_products",
"query": {
"bool": {
"should" : [
{ "match" : {"linked_products.id" :123}}
]
}
}
}
}
}

我们尝试通过两种方式查询 id 字段:

  1. Trino 查询 - 选择计数(*) 来自 es_table aaa 其中 any_match(aaa.linked_products, x-> x.id=123)

当我们尝试根据 id 字段进行查询时,不会发生 Pushdown to elastic 并且连接器会将所有文档检索到 trino(这只发生在对嵌套文档的查询中)。

  1. 将 es-query 从 trino 发送到 elastic: SELECT * FROM es.default."$query:" 它可以工作,但是当我们尝试使用许多文档检索 id 时,我们从弹性客户端超时。 我从文档中不明白是否可以在我们使用 es-query 时执行滚动以避免超时问题。

【问题讨论】:

标签: elasticsearch nested presto trino


【解决方案1】:

Trino 将nested 对象类型映射到ROW,就像它在读取期间映射标准object 类型一样。 nested 名称本身对 Trino 没有任何作用,因为它只确定对象在 Elasticsearch 中的存储方式。

假设我们将以下文档推送到您的索引。

curl -X POST "localhost:9200/product_index/_doc?pretty" 
-H 'Content-Type: application/json' -d'
{
  "id": "1",
  "name": "foo",
  "linked_products": {
      "id": "123"
  }
}
'

您在 Trino 中阅读此内容的方式就是使用标准的 ROW 语法。

SELECT 
  id, 
  name, 
  linked_products.id 
FROM elasticsearch.default.product_index;

结果:

|id |name|id |
|---|----|---|
|1  |foo |123|

这很好,但是从嵌套对象的名称是复数的事实来看,我假设您想要存储这样的对象数组。

curl -X POST "localhost:9200/product_index/_doc?pretty" -H 'Content-Type: application/json' -d'
{
  "id": "2",
  "name": "bar",
  "linked_products": [
    {
      "id": "123"
    },
    {
      "id": "456"
    }
  ]
}
'

如果您运行与上述相同的查询,插入第二个文档,您将收到以下错误。

SQL Error [58]: Query failed (#20210604_202723_00009_nskc4): Expected object for field 'linked_products' of type ROW: [{id=123}, {id=456}] [ArrayList]

这是因为 Trino 无法知道默认 Elasticsearch 映射中哪些字段是数组。因此,要启用对该数组的查询,您需要按照the instructions in the docs 使用_meta 字段将该字段明确标识为 Trino 中的数组类型。以下是本示例中用于将linked_products 识别为ARRAY 的命令。

curl --request PUT \
    --url localhost:9200/product_index/_mapping \
    --header 'content-type: application/json' \
    --data '
{
    "_meta": {
        "presto":{
            "linked_products":{
                "isArray":true
            }
        }
    }
}'

现在,您需要在 SELECT 语句中说明 linked_productsARRAY 类型的 ROW。并非所有索引都有值,因此您应该使用索引安全element_at 函数来避免错误。

SELECT 
  id, 
  name,
  element_at(linked_products, 1).id AS id1, 
  element_at(linked_products, 2).id AS id2 
FROM elasticsearch.default.product_index;

结果:

|id |name|id1|id2 |
|---|----|---|----|
|1  |foo |123|NULL|
|2  |bar |123|456 |

================================================ ==========

更新以回答@gil bob 的更新问题。

  1. 目前在 Elasticsearch 连接器中不支持下推聚合,但在 PR 7131 中添加了
  2. 您可以在elasticsearch.properties 文件中设置elasticsearch.request-timeout 属性以增加请求超时作为一种解决方法,直到发生下推。如果 Elasticsearch 需要这么长时间才能返回它,那么无论您是在 Trino 还是 Elasticsearch 中运行聚合,都需要进行设置。

【讨论】:

  • 非常感谢您的详细解答。我将尝试对我的问题进行一些澄清。我在我的问题中添加了说明
  • 嘿@gil bob,如果我更新的答案是否解决了您的问题,请告诉我,如果可以,请接受答案。 :)
  • 这解决了我的大部分问题非常感谢您的宝贵时间!
  • 嘿,吉尔鲍勃。那你介意接受这个答案吗?
猜你喜欢
  • 2022-10-07
  • 2020-08-18
  • 1970-01-01
  • 2021-03-23
  • 2011-12-29
  • 1970-01-01
  • 2022-10-04
  • 1970-01-01
  • 2020-01-08
相关资源
最近更新 更多