我是trino的新手,我正试图用它来查询弹性搜索中的嵌套对象。
这是我在弹性搜索中的映射:
{
"product_index": {
"mappings": {
"properties" :{
"id" : { "type" : "keyword"},
"name" { "type" : "keyword"},
"linked_products" :{
"type": "nested",
"properties" :{
"id" : { "type" : "keyword"}
}
}
}
}
}
}
我需要对linked_products下的id字段执行查询。trino中对id字段执行查询的语法是什么?我需要对弹性中的目标索引映射使用特殊定义来映射trino的嵌套部分吗?
=============================================
嗨,我将设法澄清我的问题。
我们正在尝试根据id字段查询数据。这是Elastic:中的查询
get product_index/_search
{
"query": {
"nested" : {
"path" : "linked_products",
"query": {
"bool": {
"should" : [
{ "match" : {"linked_products.id" :123}}
]
}
}
}
}
}
我们尝试通过两种方式查询id字段:
- Trino查询-选择计数(*(来自es_table aaa其中any_match(aaa.linked_products,x->x.id=123(
当我们尝试根据id字段进行查询时,不会发生向弹性的下推,连接器会将所有文档检索到trino(这只发生在嵌套文档上的查询中(。
- 将es查询从trino发送到elastic:SELECT*FROM默认值$查询:";它是有效的,但当我们试图用许多文档检索id时,我们从弹性客户端获得了超时。我从文档中不明白,当我们使用es查询时,是否可以执行滚动以避免超时问题
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映射中知道哪些字段是数组。因此,要启用对此数组的查询,您需要按照文档中的说明,使用_meta
字段在Trino中将该字段显式标识为array类型。以下是在本例中用于将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_products
是ROW
类型的ARRAY
。并非所有索引都有值,因此应该使用索引安全的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的更新问题。
- Elasticsearch连接器目前不支持下推聚合,但PR 7131中添加了这一点
- 您可以在
elasticsearch.properties
文件中设置elasticsearch.request-timeout
属性,以增加请求超时,作为一种变通方法,直到出现下推。如果Elasticsearch需要这么长时间才能返回,那么无论您是在Trino还是Elasticsearch中运行聚合,都需要设置它