ElasticSearch网站搜索自动完成功能行为

时间:2016-11-09 14:33:54

标签: elasticsearch

我试图在ElasticSearch网站上复制搜索功能的确切行为。

有谁知道我在哪里可以找到映射/设置的来源?以及如何执行查询?

主要要求:

  • 所有搜索都必须不区分大小写(让我们使用“小写”TokenFilter)。
  • 应突出显示匹配的搜索查询(请检查下方输出中的粗体部分)。
  • 结果的顺序很重要,基本上应首先返回与搜索查询匹配的字符数较少的“短语”,以便首先返回精确(或接近)匹配。

方案

想象一下,我有以下数据集:

ID, NAME
1,  SoftwareRocks everytime 
10, The is nothing like home
8,  Opacc Software AG is good but software is even better 
2,  Opacc Software AG 
3,  Sage KHK Software AG 
4,  Software AG 
5,  bbv Software Services AG 
6,  Software AG2 
7,  Sof on the world

测试1

输入:sof

输出

  • 4, Sof tware AG
  • 6, Sof tware AG2
  • 世界
  • 7, Sof
  • 2,Opacc Sof tware AG
  • 3,Sage KHK Sof tware AG
  • 每次
  • 1, Sof twareRocks
  • 5,bbv Sof tware Services AG
  • 8,Opacc Sof tware AG很好,但 sof tware更好

测试2

输入:软

输出

  • 4, Sof tware AG
  • 6, Sof tware AG2
  • 2,Opacc Sof tware AG
  • 3,Sage KHK Sof tware AG
  • 每次
  • 1, wareRocks
  • 5,bbv Sof tware Services AG
  • 8,Opacc Sof tware AG很好,但商品更好

测试3

输入:软件

输出

  • 4,软件 AG
  • 6,软件 AG2
  • 2,Opacc 软件 AG
  • 3,Sage KHK 软件 AG
  • 1,软件每次晃动
  • 5,bbv 软件服务AG
  • 8,Opacc 软件 AG很好,但软件更好

测试4

输入:软件ag

输出

  • 4, Software AG
  • 6, Software AG 2
  • 2,Opacc Software AG
  • 3,Sage KHK Software AG
  • 8,Opacc Software AG 很好,但软件更好

尝试1

PUT /my_index
    {
        "settings": { 
            "analysis": {
                "filter": {
                    "autocomplete_filter": { 
                        "type":     "edge_ngram",
                        "min_gram": 1,
                        "max_gram": 20
                    }
                },
                "analyzer": {
                    "autocomplete": {
                        "type":      "custom",
                        "tokenizer": "standard",
                        "filter": [
                            "lowercase",
                            "autocomplete_filter" 
                        ]
                    }
                }
            }
        }
    }

PUT /my_index/_mapping/my_type
    {
    "type": {
        "properties": {
            "name": {
                "type":            "string",
                "analyzer":  "autocomplete", 
                "search_analyzer": "standard" 
            }
        }
    }

GET /my_index/my_type/_search
{
    "query": {
        "match": {
            "name": "software"
        }
    }
}

尝试2

{"query" : {"match_phrase_prefix": { "name": "Software ag" }}}

这会正确返回,但突出显示似乎已关闭。例如:

  • 4, Software AG
  • 6, Software AG2
  • 2,Opacc Software AG
  • 3,Sage KHK Software AG
  • 8,Opacc Software AG 很好,但软件更好

我期望的是搜索词可以突出显示。返回元素的顺序应该基于整个术语的长度。

2 个答案:

答案 0 :(得分:0)

尝试此查询。这将高亮搜索搜索结果。

{
    'query':{
        'filtered':{
            'query':{
                'match':{
                    '_all':{
                        'query':"soft",
                        'type':'phrase'
                        }
                    }
                }
            }
        },
    'highlight':{
        'pre_tags':'<em>',
        'post_tags':'</em>',
        'fields':{'*':{}}
    }
}

答案 1 :(得分:0)

好的,你的用例非常简单。弹性网站上的自动完成也是非常直接的自动填充用例,但是它们具有在多个字段中构建的搜索数据集,并且字段中匹配的关键字也确定搜索结果的相关性/顺序。

为了让你保持简单,我会使用ngram tokenizer获取映射中的字符串并进行简单的过滤搜索 映射

{
    "analysis": {
        "analyzer": {           
            "autocomplete_analyzer": {
                "type": "custom",
                "tokenizer": "standard",
                "filter": ["standard", "lowercase", "asciifolding", "filter_ngram"]
            }
        },
        "filter": {
            "filter_stop": {
                "type": "stop",
                "stopwords": "_english_",
                "ignore_case": true
            },
            "filter_shingle": {
                "type": "shingle",
                "max_shingle_size": 2,
                "min_shingle_size": 2,
                "output_unigrams": true
            },
            "filter_snowball": {
                "type": "snowball",
                "language": "english"
            },
            "filter_stemmer": {
                "type": "porter_stem",
                "language": "English"
            },
            "filter_ngram": {
                "type": "nGram",
                "min_gram": 3,
                "max_gram": 15
            },
            "filter_edgengram": {
                "type": "edgeNGram",
                "min_gram": 2,
                "max_gram": 15
            },
            "filter_worddelimiter": {
                "type": "word_delimiter"
            }
        },
        "tokenizer": {
            "haystack_ngram_tokenizer": {
                "type": "nGram",
                "min_gram": 3,
                "max_gram": 15
            },
            "haystack_edgengram_tokenizer": {
                "type": "edgeNGram",
                "min_gram": 2,
                "max_gram": 15,
                "side": "front"
            }
        }
    }
}

这些映射还包括我在自动完成解决方案中使用的一些高级过滤器。

{
    "query": {
        "filtered": {
            "filter": {
                "term": {
                    "FIELD": "VALUE"
                }
            }
        }

    }
}

有关弹性的示例不会对输入的关键字进行spell-check/fuzzy查询。

如果你想添加模糊,那么你也可以看一下上面的文档,根据你的用例建立模糊查询并调整模糊度。