我有一个类似于elasticsearch的文档结构,
putchar()
我想搜索包含{
_id: 1,
name: 'abc',
post: [{
type: 'text',
url: '__url___'
}, {
type: 'image',
url: '__url___'
}, {
type: 'text',
url: '__url___'
}, {
type: 'video',
url: '__url___'
}, {
type: 'text',
url: '__url___'
}]
}
type
的帖子的文档,其中text
出现次数超过两次。是否有可能在Elasticsearch?
答案 0 :(得分:2)
选项1
您需要使用script进行此类搜索,对于名为post
的字段和名为type
的子字段:
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"script": {
"script": "_source.post.type.count(param1)>2",
"params": {
"param1": "text"
}
}
}
}
}
}
并确保您在配置文件中enable inline scripts:
script.engine.groovy.inline.search: on
选项2
此操作也可以在索引时完成,以便在使用transform
进行搜索时节省一些时间。像这样:
{
"mappings": {
"test": {
"transform": {
"script": "if(ctx._source.post.type.count(param1)>2) ctx._source['count_texts']=ctx._source.post.type.count(param1);",
"params": {
"param1": "text"
}
},
"properties": {
"name": {
"type": "string"
},
"count_texts": {
"type": "integer"
},
...
确保在配置文件中启用正确的脚本设置:
script.engine.groovy.inline.mapping: on
而且,在搜索时,像这样的查询应该这样做:
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"range": {
"count_texts": {
"gte": 2
}
}
}
}
}
}
transform
的优点是重型脚本操作是在索引时执行的,而不是在搜索时执行的,并且搜索速度可能比在搜索时使用脚本时更快。
transform
的缺点是,除非您在映射中定义另一个param1
,否则无法为transform
实际指定其他值。意思是,如果你想计算video
,该怎么办?您需要添加另一个transform
和另一个字段count_videos
,例如。