elasticsearch 自动完成建议在多个字段和多个字段上完成

问题描述 投票:0回答:1

所以我们有2个案例:

  1. 主页上的单个搜索输入

  2. 具有多个输入字段的订单

    Resultitems Homepage single searchfield Orderingform multiple search fields

总结一下:

  1. 在我们的网站上,用户搜索公司,选择一家公司,然后订购。
  2. 我们想在主页上创建一个全局搜索字段。我们有一个订单表格,其中有 4 个输入字段;公司名称、公司编号、公司地址(最常见的街道)、公司所在城市。
  3. 城市、法律形式和联邦州的聚合,用户可以将其用作过滤器
  4. 总体思路是:用户登陆主页或订购表单页面,执行搜索、过滤,然后找到公司,单击公司结果 -> 这会在订购表单中加载公司详细信息,以便用户可以订购。

问题:

  1. 我很困惑自动完成功能如何在单个全局搜索字段和具有 4(或 5)个字段的订购表单上工作
  2. 您可以帮助我们提供可用于我们场景的示例查询吗?

我们做过的事情:

  1. 将字段复制到通用字段,以便我们可以查询单个字段(例如街道、邮政编码、城市合并到 1 个 full_address 字段中)
  2. 为德国街道名称和语音创建了一个自定义分析器

咨询事项:主页搜索

  1. 单个搜索字段应搜索 all_names、all_address、company_number、all_offices(= 所有城市)并返回最高相关性
  2. 最高相关性可以通过调整查询中的“权重”和“提升”来部分实现
  3. 但是,当用户在 1 个搜索字段中输入不同的术语(例如名称 + 邮政编码 + 城市)时,我不明白“按输入搜索”完成功能如何工作
  4. 自动完成功能仅适用于前 3 个字母吗?请解释一下。

建议事项:订单搜索

  1. 订单有4个字段;公司名称、公司编号、地址、城市
  2. 理想情况下,当用户输入时,他应该在他输入的字段上获得自动补全功能
  3. 这很简单;名称字段 = 名称建议等
  4. 当填写多个字段时,自动补全是否应该只是匹配所有输入字段的建议?就像公司名称的一部分已填写,那么地址自动完成仅来自匹配的公司名称?我们应该想要这个吗?
  5. 我们是否应该在订购表单中添加像主页上那样的第五个全局搜索字段?

示例分析器和映射:

    {
        "settings": {
            "index": {
            "number_of_shards": 1,
            "number_of_replicas": 0
            },
            "analysis": {
                "filter": {
                    "german_stop": {
                    "type":       "stop",
                    "stopwords":  "_german_" 
                    },
                    "german_stemmer": {
                    "type":       "stemmer",
                    "language":   "light_german"
                    },
                    "snowball": {
                        "type": "snowball",
                        "language": "German2"
                    },
                    "german_phonetic": {
                        "type": "phonetic",
                        "encoder": "koelnerphonetik",
                        "replace": false
                    },
                    "address_synonyms": {
                        "type": "synonym",
                        "synonyms": [ "str, strasse, straße => strass" ]
                    }
                },      
                "analyzer": {
                    "names_analyzer": {
                        "type": "custom",
                        "tokenizer": "standard",
                        "char_filter": [
                            "html_strip"
                          ],
                        "filter": [
                            "lowercase",
                            "word_delimiter",
                            "german_normalization",
                            "german_phonetic",
                            "asciifolding",
                            "apostrophe"
                        ]
                    },
                    
                    "address_analyzer": {
                        "type": "custom",
                        "tokenizer": "standard",
                        "filter": [
                            "lowercase",
                            "german_normalization",
                            "german_stop",
                            "snowball",
                            "german_stemmer",
                            "address_synonyms",
                            "german_phonetic",
                            "asciifolding",
                            "apostrophe",
                            "word_delimiter"
                        ]
                    },
    
                    "keyword_analyzer": {
                        "type": "custom",
                        "tokenizer": "standard",
                        "filter": [
                            "lowercase",
                            "german_normalization",
                            "asciifolding"
                        ]
                    }
                }
            }
        },
        "mappings": {
            "properties": {
    
                "all_names":{
                    "type":"text",
                    "analyzer": "names_analyzer",
                    "fields":{
                        "search-as-you-type":{
                        "type":"search_as_you_type"
                        }
                    }
                },
    
                "name":{
                    "type":"text",
                    "analyzer": "names_analyzer",
                    "copy_to": "all_names"
                },
        
                "alt_names":{
                    "type":"nested",
                    "include_in_root": true, 
                    "properties":{
                        "name": {
                            "type": "text",
                            "analyzer": "names_analyzer",
                            "copy_to": "all_names"                  },
                        "office":{
                            "type": "keyword",
                            "copy_to": "all_offices",
                            "fields":{
                                "text":{
                                    "type":"text"
                                },
                                "keyword_analyzed":{
                                    "type":"text",
                                    "analyzer":"keyword_analyzer"
                                }
                            }
                        }
                    }
                },
                "branches":{
                    "type":"nested",
                    "include_in_root": true, 
                    "properties":{
                        "name": {
                            "type": "text",
                            "analyzer": "names_analyzer",
                            "copy_to": "all_names"
                        },
                        "office":{
                            "type": "keyword",
                            "copy_to": "all_offices",
                            "fields":{
                                "text":{
                                    "type":"text"
                                },
                                "keyword_analyzed":{
                                    "type":"text",
                                    "analyzer":"keyword_analyzer"
                                }
                            }
                        }
                    }
                },
        
                "full_address":{
                    "type":"text",
                    "analyzer": "address_analyzer",
                    "fields":{
                       "search-as-you-type":{
                          "type":"search_as_you_type"
                       }
                    }
                 },
    
                 "all_address":{
                    "type":"text",
                    "analyzer": "address_analyzer",
                    "fields":{
                       "search-as-you-type":{
                          "type":"search_as_you_type"
                       }
                    }
                 },
                 "street":{
                    "type":"text",
                    "analyzer": "address_analyzer",
                    "copy_to": "all_address",
                    "fields":{
                        "search-as-you-type":{
                            "type":"search_as_you_type"
                        }
                    }
                },
                "zipcode":{
                    "type":"keyword",
                    "copy_to": "all_address",
                    "fields":{
                        "search-as-you-type":{
                            "type":"search_as_you_type"
                        },
                        "text": {
                            "type":"text"
                        }
                    }
                },
                "city":{
                    "type":"keyword",
                    "copy_to": [ "all_offices", "all_address" ],
                    "fields":{
                        "search-as-you-type":{
                            "type":"search_as_you_type"
                        },
                        "text":{
                            "type":"text",
                            "analyzer": "address_analyzer"
                        }
                    }
                 },
    
                 "legal_form":{
                    "type":"keyword",
                    "fields":{
                       "search-as-you-type":{
                          "type":"search_as_you_type"
                       },
                       "text":{
                        "type":"text"
                    }
                    }
                 },
    
                 "all_offices":{
                    "type":"keyword",
                    "fields":{
                       "search-as-you-type":{
                          "type":"search_as_you_type"
                       },
                       "text":{
                        "type":"text"
                    }
                    }
                 },
    
                 "office":{
                    "type":"keyword",
                    "copy_to": "all_offices"
                 },
        
                 "registrar":{
                    "type":"keyword",
                    "copy_to": "all_offices"
                 },
        
                 "former_registrar":{
                    "type":"keyword",
                    "copy_to": "all_offices"
                 },
        
                 "state":{
                    "type":"keyword",
                    "fields":{
                       "text":{
                        "type":"text"
                        }
                    }
                 },
        
                 "company_number":{
                    "type":"keyword",
                    "fields":{
                       "search-as-you-type":{
                          "type":"search_as_you_type"
                       },
                       "text":{
                        "type":"text"
                        }
                    }
                 },
        
                 "status":{
                    "type":"keyword",
                    "fields":{
                       "text":{
                        "type":"text"
                        }
                    }
                 }
    
            
            }
          }
    
    }

全局搜索查询示例:

    {
        "query": {
            "bool": { 
                "should": [
                    { 
                    "multi_match": {
                        "query": "Hans-Sachs-Straße",
                        "fuzziness": "AUTO",
                        "minimum_should_match": "60%"
                        }
                    }
                ],
                "filter": [ 
                    { "term":  { "state": "" }},
                    { "term":  { "all_offices": "" }}
                ]
            }
        },
        "highlight": {
            "fields": {
                "name": {},
                "full_address": {},
                "office": {},
                "company_number": {},
                "registrar": {},
                "native_company_number": {}
            }
        },
        "aggs": {
            "states": {
            "terms": { "field": "state" }
            },
            "city": {
            "terms": { "field": "all_offices" }
            }
      }
      }

订单查询示例:

    {
        "query": {
            "bool": { 
                "should": [               
                    {
                        "multi_match": {
                            "query": "str",
                            "minimum_should_match": "60%",
                            "boost": 2,
                            "fields": [
                            "full_address.search-as-you-type",
                            "full_address.search-as-you-type._2gram",
                            "full_address.search-as-you-type._3gram"
                            ]
                            }
                    },
                    {
                        "multi_match": {
                            "query": "HR",
                            "minimum_should_match": "60%",
                            "boost": 5,
                            "fields": [
                            "company_number.search-as-you-type",
                            "company_number.search-as-you-type._2gram",
                            "company_number.search-as-you-type._3gram"
                            ]
                            }
                    },
                    {
                        "multi_match": {
                            "query": "DK",
                            "minimum_should_match": "60%",
                            "boost": 5,
                            "fields": [
                            "all_names.search-as-you-type",
                            "all_names.search-as-you-type._2gram",
                            "all_names.search-as-you-type._3gram"
                            ]
                            }
                    },
                    {
                        "multi_match": {
                            "query": "Dus",
                            "minimum_should_match": "60%",
                            "boost": 3,
                            "fields": [
                            "all_offices.search-as-you-type",
                            "all_offices.search-as-you-type._2gram",
                            "all_offices.search-as-you-type._3gram"
                            ]
                            }
                    }                                                   
                ]
            },
            "filter": [ 
                { "term":  { "state": "" }},
                { "term":  { "all_offices": "" }}
            ]
        },
        "highlight": {
            "fields": {
                "name": {},
                "full_address": {},
                "office": {},
                "company_number": {},
                "registrar": {},
                "native_company_number": {}
            }
        },
        "aggs": {
            "states": {
            "terms": { "field": "state" }
            },
            "city": {
            "terms": { "field": "all_offices" }
            }
      }
    }

elasticsearch autocomplete autosuggest search-suggestion
1个回答
0
投票

这就是自动完成功能如何适用于具有不同

fields
数据类型的多个字段。

我在这些字段上也启用了

analyzers
search_analyzers
,因此我正在利用子字符串(基于
n-gram tokenziers
)搜索。

_settings
创建索引:

PUT /yourIndexName
{
  "settings": {
    "index.number_of_replicas": 0,
    "index.max_ngram_diff": 15,
    "index.default_pipeline": "your_pipeline - if any else remove this",
    "analysis": {
      "analyzer": {
        "autocomplete": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "autocomplete_filter"
          ]
        },
        "standardTokenizer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase"
          ]
        }
      },
      "filter": {
        "autocomplete_filter": {
          "type": "ngram",
          "min_gram": 2,
          "max_gram": 15
        }
      }
    }
  }
}

_mappings
为您的索引:

PUT /yourIndexName/_mapping
{
  "properties": {
    "yourFieldName0": { //or yourObject.yourFieldName
      "type": "text",
      "analyzer": "autocomplete",
      "search_analyzer": "standard",
      "fields": {
        "suggest": {
          "type": "search_as_you_type"
        },
        "keyword": {
          "type": "keyword"
        }
      }
    },
    "yourFieldName1": { //this is a simple string
      "type": "text",
      "analyzer": "autocomplete",
      "search_analyzer": "standard",      
      "fields": {
        "suggest": {
          "type": "search_as_you_type"
        }
      }
    },
    "yourFieldName2": { //this is an array of strings.
      "type": "text",
      "analyzer": "standardTokenizer",
      "search_analyzer": "standard",
      "fields": {
        "suggest": {
          "type": "search_as_you_type"
        }
      }
    },
    "locations": {
      "type": "geo_point"
    },
    "yourFieldName3": { //array of strings. it is used for facets.
      "type": "text",
      "fields": {
        "keyword": {
          "type": "keyword"
        }
      }
    }
  }
}

将数据插入索引后。现在,让我们介绍一下

search-ui
https://docs.elastic.co/search-ui/tutorials/elasticsearch

const config = {
  searchQuery: {
    search_fields: {
      "yourFieldName0.suggest": { weight: 3, snippet: { size: 50, fallback: false }},
      "yourFieldName1.suggest": {snippet: { size: 50, fallback: false }},
      "yourFieldName2.suggest": {snippet: { size: 50, fallback: false }}
    },
    result_fields: {
      resultsPerPage: 5,
      _id: {}, name: {}, yourFieldName0: { snippet: { size: 50, fallback: false } }
    },
    disjunctiveFacets: ["yourFieldName0.suggest"],
    facets: {
      "yourFieldName0.keyword": { type: "value" },
      "yourFieldName3.keyword": { type: "value" },
      locations: {
        center: "42.0001, -73.0005",
        type: "range",
        unit: "km",
        ranges: [
          { from: 0, to: 5, name: "With in 5 Km" },
          { from: 0, to: 20, name: "With in 20 Km" },
          { from: 0, to: 150, name: "With in 150 Km" },
        ],
      }
    }
  },
  autocompleteQuery: {
    results: { //this is how you can enable autocomplete on multiple fields.
      search_fields: {
        "yourFieldName0.suggest": { weight: 3, snippet: { size: 50, fallback: false } },
        "yourFieldName0": { weight: 3, snippet: { size: 50, fallback: false } },
        "yourFieldName1.suggest": {snippet: { size: 50, fallback: false }},
        "yourFieldName1": {snippet: { size: 50, fallback: false }},
      },
      result_fields: {
        _id: {}, yourFieldName0: { snippet: { size: 50, fallback: false } }
      }
    }
  },
  apiConnector: connector,
  alwaysSearchOnInitialLoad: true,
  initialState: {
    resultsPerPage: 10,
    sortList: [ { field: "_score", direction:"desc" }, { field: "yourFieldName0", direction:"asc" } ]
  }
};
© www.soinside.com 2019 - 2024. All rights reserved.