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
order
的 index
索引
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_list
为 nested
的时候 就不是这样存储了,会单独存储。详见 nested 文档
这样存主要是符合 ES
数据库的理念以搜索为主,因为这样 搜索 1000
的时候和搜索 2000
的时候都能找到这个文档,id
也是同样的道理。
理解了这个我们就可以很好的理解 上面正确的写法了。因为我们看 sku_list
的 length
也就 sku_list
中 id
的个数或 price
的个数。