所以我们有2个案例:
总结一下:
问题:
我们做过的事情:
咨询事项:主页搜索
建议事项:订单搜索
示例分析器和映射:
{
"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" }
}
}
}
这就是自动完成功能如何适用于具有不同
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" } ]
}
};