elasticscript 通过 script 查询数组长度

错误信息

    "script_stack" : [
      "org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:65)",
      "org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:27)",
      "doc['sku_list'].size() === 1",
      "    ^---- HERE"
    ],

加入我有一个 ES orderindex 索引

order 里面存的每个 doc 文档的数据格式大致如下

{
    id: 11111,
    phone: '17679873242',
    address: '地球村',
    sku_list: [
        {
            id: 'sku1',
            price: '1000'
        },
        {
            id: 'sku2',
            price: '2000'
        }

    ]
}
// ...

需求

找到所有 sku_list length = 1 的 文档 (行数据)。

实现过程

最开始一直这么写:(错误的 ❌)

GET order/_search
{
  "query": {
    "script": {
      "script": "doc['sku_list'].size() === 1"
    }
  }
}

这样写的 一直报文章开头的错误。

正确的写法 ✔

GET order/_search
{
  "query": {
    "script": {
      "script": "doc['sku_list.id'].size() === 1"
    }
  }
}

当然也可以将 size() 替换成 length。 (我用的 elasticscript 版本为 7.12.0)

GET order/_search
{
  "query": {
    "script": {
      "script": "doc['sku_list.id'].length === 1"
    }
  }
}

反思

之所以会写错误的写法 是因为对 elasticscript 对数组的理解没有理解到位。文档在不是 nested 文档的时候 是这样存数组的。

以上面的数据格式为例

在 ES 数据库存的格式为

{
    id: 11111,
    phone: '17679873242',
    address: '地球村',
    sku_list.id: [ 'sku1', 'sku1' ],
    sku_list.price: [ '1000', '2000' ]
}

提示: 当 sku_listnested 的时候 就不是这样存储了,会单独存储。详见 nested 文档

这样存主要是符合 ES 数据库的理念以搜索为主,因为这样 搜索 1000 的时候和搜索 2000 的时候都能找到这个文档,id 也是同样的道理。

理解了这个我们就可以很好的理解 上面正确的写法了。因为我们看 sku_listlength 也就 sku_listid 的个数或 price 的个数。

参考

Script query

ES 嵌套对象 旧版中文版

Nested query 最新版英文版

posted @ 2021-06-08 16:16  暗恋桃埖源  阅读(2692)  评论(0编辑  收藏  举报