我试图根据文档标题构建自动建议。如果用户键入“南方”,则自动建议将建议“韩国”'例如。我使用 shingle 过滤器将标题分为两个单词。这是我的映射:
{
"settings":{
"analysis":{
"filter":{
"suggestions_shingle":{
"type":"shingle",
"min_shingle_size":2,
"max_shingle_size":2
}
},
"analyzer":{
"suggestions":{
"tokenizer":"standard",
"filter":[
"suggestions_shingle"
]
}
}
}
},
"mappings":{
"docs":{
"properties":{
"docs_title":{
"type":"multi_field",
"fields":{
"docs_title":{
"type":"string"
},
"suggestions":{
"type":"string",
"analyzer":"suggestions",
"search_analyzer":"simple"
}
}
}
}
}
}
}
这是我的疑问:
{
explain:true,
"aggs":{
"description_suggestions":{
"terms":{
"field":"docs_title.suggestions",
"size":10,
"include":"South .*"
}
}
},
size:0
}
以下是查询的回复:
{
"took": 2764,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 453526,
"max_score": 0,
"hits": []
},
"aggregations": {
"description_suggestions": {
"doc_count_error_upper_bound": 10,
"sum_other_doc_count": 2363,
"buckets": [
{
"key": "South Korea",
"doc_count": 274
},
{
"key": "South India",
"doc_count": 179
},
{
"key": "South Carolina",
"doc_count": 179
}
]
}
}
}
如您所见,查询完成了2764次。如何加快查询速度?
我正在考虑仅在最后的2000个文档上运行聚合查询,以通过使用过滤器加快速度。我注意到Elastic Search忽略了过滤器,它在所有文档上运行aggs。这是查询:
{
explain:true,
"aggs":{
"recent_suggestions":{
"filter":{
"range":{
"docs_date":{
"gte":1453886958
}
}
},
"aggs":{
"description_suggestions":{
"terms":{
"field":"docs_title.suggestions",
"size":10,
"include":"South .*"
}
}
}
}
},
size:0
}
以下是回复:
{
"took": 2216,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 453526,
"max_score": 0,
"hits": []
},
"aggregations": {
"recent_suggestions": {
"doc_count": 27240,
"description_suggestions": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 173,
"buckets": [
{
"key": "South Korea",
"doc_count": 19
},
{
"key": "South India",
"doc_count": 17
},
{
"key": "South Carolina",
"doc_count": 17
}
]
}
}
}
}
如您所见,总命中率是相同的。
如何让这两个查询更快?
我在单个实例上使用AWS ElasticSaerch v1.5.2和Lucene v4.10.4。
答案 0 :(得分:1)
这里的问题是所有文件被认为是非常昂贵的聚合,因此需要花费很多时间。
1)首先查询:
{
"query": {
"match": {
"docs_title": "south"
}
},
"aggs": {
"unique": {
"terms": {
"field": "docs_title.suggestions",
"size": 10,
"include": "(?i)south .*",
"execution_hint": "map"
}
}
},
"size": 0
}
我们只考虑其中包含south
的文档进行聚合。您没有指定任何查询,默认情况下它是match all
查询。我还在(?i)
中添加了include
不区分大小写的标记,以便它匹配韩国和韩国。
2)第二次查询:
我们需要缩小满足我们聚合标准的文档集。
{
"query": {
"filtered": {
"query": {
"match": {
"docs_title": "south"
}
},
"filter": {
"range": {
"docs_date": {
"gte": 1453886958
}
}
}
}
},
"aggs": {
"unique": {
"terms": {
"field": "docs_title.suggestions",
"size": 10,
"include": "(?i)south .*",
"execution_hint": "map"
}
}
},
"size": 0
}
最近的文档过滤应该在查询内部进行,而不是在这种情况下进行聚合。
你现在应该看到相当大的差异。以前聚合是在450K文档上完成的,现在它应该小得多。
EDIT1 :This issue提供了有关include/exclude
<{1}}成本高{+ 1}} doc_title.suggestions
成本高的详细信息"execution_hint": "map"
是什么(带状疱疹增加)这更多)。 @markharwood评论了这个问题
基本上,aggs正在浏览索引中的所有术语。解决方案是在聚合中使用根本原因是IncludeExclude.acceptedGlobalOrdinals() 方法急切地为索引中的所有术语枚举术语而不是 懒惰地为结果集中的人。对于高基数领域这个 可能需要很长时间
<script>
$(document).ready(function(){
$('.send').attr('disabled',true);
$('#kagawad').keyup(function(){
if($(this).val() != ""){
$('.send').attr('disabled', false);
}
else
{
$('.send').attr('disabled', true);
}
})
});
</script>
,这将避免加载全局序数。 More就此而言。也没有100%的保证。来自文档
请注意,Elasticsearch会忽略此执行提示 不适用,没有向后兼容性 保证这些提示。
当少数文档与查询匹配时,将考虑这种情况。
注意:这可能完全不相关,但您可能需要查看completion suggester,但它仅在字符串以特定字母开头时才有效。