【Elasticsearch】Elasticsearch中 使用Suggesters 推荐推荐查询

文章目录

  • 【Elasticsearch】Elasticsearch中 使用Suggesters 推荐推荐查询
    • Term suggester
    • Phrase Suggester
    • Completion Suggester
    • Context Suggester

Suggesters
Suggests similar looking terms based on a provided text by using a suggester.
顾名思义,就是推荐查询你,在你输一些关键词的时候对这些词语一个建议。(百度搜索框中你每次输入的值都会帮你纠错,或者进行一个搜索推荐就是这种方式实现)
Suggesters在有4种不同的类型:
在官方文档中也是给出了详细的解释

  • Term suggester
  • Phrase Suggester
  • Completion Suggester
  • Context Suggester

官方文档

Term suggester

  • 国际惯例,先准备基础数据
POST product_en/_bulk
{"index":{"_id":"1"}}
{"title":"my english book","desc":"this is noob english dictionary","price":13.90,"tag":["dictionary","english","noob"]}
{"index":{"_id":"2"}}
{"title":"my chinese book","desc":"this is noob chinese dictionary","price":15.90,"tag":["dictionary","chinese","noob"]}
{"index":{"_id":"3"}}
{"title":"switch oled","desc":"Nintendo Switch","price":2499,"tag":["game","switch","video game","Handheld game console"]}
{"index":{"_id":"4"}}
{"title":"iPhone 14","desc":"smart mobile phone","price":8999,"tag":["Apple","mobile phone","IOS"]}
{"index":{"_id":"5"}}
{"title":"IPad","desc":"smart tablet","price":12990,"tag":["tablet","Apple","IOS"]}
{"index":{"_id":"6"}}
{"title":"Dove Chocolate","desc":"Dove, enjoy the silky","price":8.00,"tag":["chocolate","Dove","silky"]}
  • 推荐查询[term suggest]单个短语进行推荐
GET product_en/_search
{"suggest":{"my_suggestions":{"text": "englis","term":{"suggest_mode":"always","field":"title"}}}
}
  • 结果
    可以看出虽然在查询的时候,故意写错了”englis“ 这个单词,elastic还是根据term suggest 推荐返回了一个推荐的值。(还有一定的纠错功能)【在options 这个对象中】
{"took": 1,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 0,"relation": "eq"},"max_score": null,"hits": []},"suggest": {"my_suggestions": [{"text": "englis","offset": 0,"length": 6,"options": [{"text": "english","score": 0.8333333,"freq": 1}]}]}
}
  • 同样也可以响官方文档给出的示例一样,可以多指定机构几个”suggestion“

Several suggestions can be specified per request.(可以为每个请求指定几个建议。)

GET product_en/_search
{"suggest":{"my_suggestions_1":{"text": "phone","term":{"suggest_mode":"popular","field":"title"}},"my_suggestions_2":{"text": "englis","term":{"suggest_mode":"always","field":"title"}}}
}
  • 结果:
{"took": 1,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 0,"relation": "eq"},"max_score": null,"hits": []},"suggest": {"my_suggestions_1": [{"text": "phone","offset": 0,"length": 5,"options": []}],"my_suggestions_2": [{"text": "englis","offset": 0,"length": 6,"options": [{"text": "english","score": 0.8333333,"freq": 1}]}]}
}

细心的同学可能发现上面的一个字段叫:suggest_mode
看了下官方文档一脸懵。
The suggest mode controls what suggestions are included or controls for what suggest text terms, suggestions should be suggested. Three possible values can be specified:

missing: Only provide suggestions for suggest text terms that are not in the index. This is the default.
popular: Only suggest suggestions that occur in more docs than the original suggest text term.
always: Suggest any matching suggestions based on terms in the suggest text.

其实大致意思如下,(可以按照对应的值传入后体验下):

  • suggest_mode:搜索推荐的推荐模式,参数值亦是枚举:

    • missing:默认值,仅为不在索引中的词项生成建议词:仅仅返回可推荐的词语,如果已经精确匹配到了一个文档中的内容,就不会再进行“纠错”或者“推荐”
    • popular:仅返回与搜索词文档词频或文档词频更高的建议词:意思值返回返回文档词频更高的词语。比如:文档内容中同时出现了"book"和“books” 但是“books”这个单词在整合文档中出现的次数比"book"出现的次数多,那么elastic就回去推荐“books”这个词,但是输入的此项并不推荐。
    • always:根据 建议文本中的词项 推荐 任何匹配的建议词,推荐所有建议,并不做限制。

Phrase Suggester

这个名字的意思就是,短语建议。
官方文档这样写道:
The term suggester provides a very convenient API to access word alternatives on a per token basis within a certain string distance. The API allows accessing each token in the stream individually while suggest-selection is left to the API consumer. Yet, often pre-selected suggestions are required in order to present to the end-user. The phrase suggester adds additional logic on top of the term suggester to select entire corrected phrases instead of individual tokens weighted based on ngram-language models. In practice this suggester will be able to make better decisions about which tokens to pick based on co-occurrence and frequencies.
In general the phrase suggester requires special mapping up front to work. The phrase suggester examples on this page need the following mapping to work. The reverse analyzer is used only in the last example.(这段话的大致意思就是如果我们要去使用Phrase Suggester 的话,我们应该按照下面这个例子创建一个特殊的索引文档来使用)。接下来我们看以下这个特殊的mapping:

PUT test
{"settings": {"index": {"number_of_shards": 1,"analysis": {"analyzer": {"trigram": {"type": "custom","tokenizer": "standard","filter": ["lowercase","shingle"]},"reverse": {"type": "custom","tokenizer": "standard","filter": ["lowercase","reverse"]}},"filter": {"shingle": {"type": "shingle","min_shingle_size": 2,"max_shingle_size": 3}}}}},"mappings": {"properties": {"title": {"type": "text","fields": {"trigram": {"type": "text","analyzer": "trigram"},"reverse": {"type": "text","analyzer": "reverse"}}}}}
}

细心的人应该发现了这个mapping使用了分片。而且创建了一个自定义分词器,其中切词器tokenizer官方使用了默认的standard。和自定义的shingle令牌过滤器。这里可能需要引入一个新的令牌过滤器。这个令牌过滤器叫shingle。shingle 官方文档 这样解释道:

1、Add shingles, or word n-grams, to a token stream by concatenating adjacent tokens. By default, the shingle token filter outputs two-word shingles and unigrams.
2、For example, many tokenizers convert the lazy dog to [ the, lazy, dog ]. You can use the shingle filter to add two-word shingles to this stream: [ the, the lazy, lazy, lazy dog, dog ].

上面表示,你可以使用shingle[ the, lazy, dog ] 通过不同力度切分为多种不同的短语组合,因为种的例子是切分后的结果。(各位老板感觉是不是很像trigram
感兴趣的老铁可以感受一下,我给各位准备好了示例。

# 使用 trigram 进行分词
GET test/_analyze
{"analyzer": "trigram","text":"lucene and elasticsearch"
}
# 使用 shingle
GET test/_analyze
{"tokenizer": "whitespace","filter": [ "shingle" ],"text": "lucene and elasticsearch"
}

还有就是
min_shingle_sizemax_shingle_size: 这两参数:是可以设置你的短语分词力度。这里最小设置了2,在这样的设置下结果展示如下:(感兴趣的小伙伴可以去调试以下别的参数)

{"tokens": [{"token": "lucene","start_offset": 0,"end_offset": 6,"type": "<ALPHANUM>","position": 0},{"token": "lucene and","start_offset": 0,"end_offset": 10,"type": "shingle","position": 0,"positionLength": 2},{"token": "lucene and elasticsearch","start_offset": 0,"end_offset": 24,"type": "shingle","position": 0,"positionLength": 3},{"token": "and","start_offset": 7,"end_offset": 10,"type": "<ALPHANUM>","position": 1},{"token": "and elasticsearch","start_offset": 7,"end_offset": 24,"type": "shingle","position": 1,"positionLength": 2},{"token": "elasticsearch","start_offset": 11,"end_offset": 24,"type": "<ALPHANUM>","position": 2}]
}

这里再拓展一个参数,加到 shingle里面

     "shingle": {"type": "shingle","min_shingle_size": 2,"max_shingle_size": 3,## 下面这个(output_unigrams)是关闭原始词项的开关(默认打开 true),## 执行后不会出现单个此项的结果,执行时删除此2行"output_unigrams": false }

官方文档的意思是:
output_unigrams:(Optional, Boolean) If true, the output includes the original input tokens. If false, the output only includes shingles; the original input tokens are removed. Defaults to true.
大致意思就是,结果中是否需要出现原词项(不明白?接着往下看,我会以一个例子的形式为你解释什么叫output_unigrams
这时候通过分词器进行分词时候就没有单个单词的option了(一般实际使用时候去操作合这个开关)。这里买下一个伏笔,这个开关会影响到 Phrase Suggester 的使用。想了解可以继续往下看。


  • 学习了和创建好上面的mapping后,接下来执行测试数据
    下面这段是数据有些单词让我进行了一些特殊的处理。把单词字母调换来验证。
POST test/_bulk
{"index":{"_id":1}}
{"title":"lucene and elasticsearch"}
{"index":{"_id":2}}
{"title":"lucene and elasticsearhc"}
{"index":{"_id":3}}
{"title":"luceen and elasticsearch"}
  • 进行查询,并且按照管饭示例进行结果高亮
GET test/_search
{"suggest": {"text": "Luceen and elasticsearhc","simple_phrase": {"phrase": {"field": "title.trigram","max_errors": 2,"gram_size":1,"confidence":1,"direct_generator": [{"field": "title.trigram","suggest_mode": "always"}],"highlight": {"pre_tag": "<em>","post_tag": "</em>"}}}}
}
  • 结果 发现es 把我们输入的错误单词都进行了纠错,并且按照文档中出现的此项进行了推荐(我只能说Es牛B…)
{"took": 2,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 0,"relation": "eq"},"max_score": null,"hits": []},"suggest": {"simple_phrase": [{"text": "Luceen and elasticsearhc","offset": 0,"length": 24,"options": [{"text": "lucene and elasticsearch","highlighted": "<em>lucene</em> and <em>elasticsearch</em>","score": 0.049228575},{"text": "luceen and elasticsearch","highlighted": "luceen and <em>elasticsearch</em>","score": 0.04369737},{"text": "lucene and elasticsearhc","highlighted": "<em>lucene</em> and elasticsearhc","score": 0.041798845}]}]}
}

这里为小伙伴解释一下上面关于output_unigrams这个参数的使用小问题
使用以下语句删 test 这个mapping 然后重新创建这个mapping,并且把output_unigrams这个开管打开。然后再次填入相同的数据,使用上面的查询语句进行查询的时候,我么会发现。es报错了?

DELETE test
  • 报错信息如下:

At least one unigram is required but all tokens were ngrams

{"error": {"root_cause": [{"type": "illegal_state_exception","reason": "At least one unigram is required but all tokens were ngrams"}],"type": "search_phase_execution_exception","reason": "all shards failed","phase": "query","grouped": true,"failed_shards": [{"shard": 0,"index": "test","node": "xLs8XZPuTlGCU3Ac9hak1g","reason": {"type": "illegal_state_exception","reason": "At least one unigram is required but all tokens were ngrams"}}],"caused_by": {"type": "illegal_state_exception","reason": "At least one unigram is required but all tokens were ngrams","caused_by": {"type": "illegal_state_exception","reason": "At least one unigram is required but all tokens were ngrams"}}},"status": 500
}

这是为什么呢?
查阅官方文档得知,这里可以去官方文档去查看就在Phrase Suggester 这一栏可以找到。在使用 Phrase Suggester 的时候,我么需要指定Candidate Generators 候选者生成器,这也是我们Query DSL 语句中,需要指定的一个字段direct_generator。官方也给出解释了其含义。

Candidate Generators:

The phrase suggester uses candidate generators to produce a list of possible terms per term in the given text. A single candidate generator is similar to a term suggester called for each individual term in the text. The output of the generators is subsequently scored in combination with the candidates from the other terms for suggestion candidates.

Currently only one type of candidate generator is supported, the direct_generator. The Phrase suggest API accepts a list of generators under the key direct_generator; each of the generators in the list is called per term in the original text.

上文的大致意思是:
关于direct_generator:phrase suggester使用时候选定的生成器生成给定文本中每个项可能的项的列表。单个候选生成器类似于为文本中的每个单独的调用term suggester。生成器的输出随后与建议候选项中的候选项结合打分。目前只支持一种候选生成器,即direct_generator。建议API直接生成器下的生成器列表;列表中的每个生成器都按原始文本中的每个项调用。(按照这个意思来看的话,这个短语推荐看来也是通过 term suggester实现的并且有大量的内存计算)

既然都是term 实现的,那么term又是更加每个此项进行推荐,当你关闭了output_unigrams这个参数的时候,不会有再有单个词汇推荐了,这样的话候生成器也无法正常工作了,也应对了官方文档的解释,phrase suggester是基于term suggester 和 direct_generato配合实现的。

Completion Suggester

The completion suggester provides auto-complete/search-as-you-type functionality. This is a navigational feature to guide users to relevant results as they are typing, improving search precision. It is not meant for spell correction or did-you-mean functionality like the term or phrase suggesters.

Ideally, auto-complete functionality should be as fast as a user types to provide instant feedback relevant to what a user has already typed in. Hence, completion suggester is optimized for speed. The suggester uses data structures that enable fast lookups, but are costly to build and are stored in-memory.

大致意思就是,它主要针对的应用场景就是"Auto Completion"(自动匹配),此场景下用户每输入一个字符的时候,就需要即时发送一次查询请求到后端查找匹配项,在用户输入速度较高的情况下对后端响应速度要求比较苛刻,是一种自动完全补全,而且是基于内存的FST结构,感兴趣的同学可以看一下,基于这个结构是一种压缩技术,这种技术可以把TB级别的数据压缩GB,可想而知性能有多强。 因此实现上它和前面两个Suggester采用了不同的数据结构,索引并非单单通过倒排来完成,而是将analyze过的数据编码成FST和索引一起存放。但是由于使用了FST,和类似于AC自动机的匹配技术,缺点就是只能使用前缀索引

  • 话不多说上mapping
    可以看出,这mapping和之前的mapping在字段定义上有了一些不同,我们需要在指定建议字段的时候专门去指定为completion类型。
PUT suggest_iphone
{"mappings": {"properties": {"title":{"type": "text","analyzer": "ik_max_word","fields": {"suggest":{"type":"completion","analyzer":"ik_max_word"}}},"content":{"type":"text","analyzer": "ik_max_word"}}}
}
  • 批量数据
POST _bulk
{"index":{"_index":"suggest_iphone","_id":1}}
{"title":"IPhone 14","content":"年度旗舰,超级性能"}
{"index":{"_index":"suggest_iphone","_id":2}}
{"title":"IPhone 12","content":"我是14它弟"}
{"index":{"_index":"suggest_iphone","_id":3}}
{"title":"IPhone 11","content":"我是假货"}
{"index":{"_index":"suggest_iphone","_id":4}}
{"title":"IPhone 10 ","content":"我其实叫IPhone X"}
{"index":{"_index":"suggest_iphone","_id":5}}
{"title":"IPhone 8","content":"我是里程碑的机器,我还有Home键位"}
{"index":{"_index":"suggest_iphone","_id":6}}
{"title":"IPhone 7","content":"我是IPhone7它弟"}
{"index":{"_index":"suggest_iphone","_id":7}}
{"title":"IPhone 6s","content":"我是单摄像头"}
{"index":{"_index":"suggest_iphone","_id":8}}
{"title":"IPhone 6","content":"是最没用,而且最垃圾一代"}
{"index":{"_index":"suggest_iphone","_id":9}}
{"title":"IPhone 5s","content":"我是方方正正,加长IPhone5s"}
{"index":{"_index":"suggest_iphone","_id":10}}
{"title":"IPhone 5","content":"我是方方正正,加长IPhone4"}
  • 开始查询
# 这些suggest 是相互结合起来使用
# 1、completion
GET suggest_iphone/_search?pretty
{"suggest": {"phone_suggest": {"text": "IPhone","completion": {"field": "title.suggest"}}}
}# 2、模糊查询,都是基于 prefix 前缀查询,官方说明只支持前缀的查询。(注意这里这里的Iphone 并没有输入完全,是通过模糊查询出来的)
GET suggest_iphone/_search
{"suggest": {"phone_suggest": {"text": "Iphon 6s","completion": {"field": "title.suggest","skip_duplicates":true,"fuzzy":{"fuzziness":1}}}}
}
# 3、模糊查询,都是基于 prefix 前缀查询,官方说明只支持前缀的查询。(其实和第二种没什么区别  )
GET suggest_iphone/_search
{"suggest": {"phone_suggest": {"prefix": "Iphon","completion": {"field": "title.suggest","skip_duplicates":true,"fuzzy":{"fuzziness":1}}}}
}
  • 查询结果
结果
# 1、completion 结果
{"took": 1,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 0,"relation": "eq"},"max_score": null,"hits": []},"suggest": {"phone_suggest": [{"text": "IPhone","offset": 0,"length": 6,"options": [{"text": "IPhone 10 ","_index": "suggest_iphone","_id": "4","_score": 1,"_source": {"title": "IPhone 10 ","content": "我其实叫IPhone X"}},{"text": "IPhone 11","_index": "suggest_iphone","_id": "3","_score": 1,"_source": {"title": "IPhone 11","content": "我是假货"}},{"text": "IPhone 12","_index": "suggest_iphone","_id": "2","_score": 1,"_source": {"title": "IPhone 12","content": "我是14它弟"}},{"text": "IPhone 14","_index": "suggest_iphone","_id": "1","_score": 1,"_source": {"title": "IPhone 14","content": "年度旗舰,超级性能"}},{"text": "IPhone 5","_index": "suggest_iphone","_id": "10","_score": 1,"_source": {"title": "IPhone 5","content": "我是方方正正,加长IPhone4"}}]}]}
}结果
# 2、模糊查询,都是基于 prefix 前缀查询,官方说明只支持前缀的查询。(模糊查询查出结果)
{"took": 0,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 0,"relation": "eq"},"max_score": null,"hits": []},"suggest": {"phone_suggest": [{"text": "Iphon 6s","offset": 0,"length": 8,"options": [{"text": "IPhone 6s","_index": "suggest_iphone","_id": "7","_score": 5,"_source": {"title": "IPhone 6s","content": "我是单摄像头"}}]}]}
}结果
# 3、模糊查询,都是基于 prefix 前缀查询,官方说明只支持前缀的查询。
{"took": 0,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 0,"relation": "eq"},"max_score": null,"hits": []},"suggest": {"phone_suggest": [{"text": "Iphon 6s","offset": 0,"length": 8,"options": [{"text": "IPhone 6s","_index": "suggest_iphone","_id": "7","_score": 5,"_source": {"title": "IPhone 6s","content": "我是单摄像头"}}]}]}
}

Context Suggester

The completion suggester considers all documents in the index, but it is often desirable to serve suggestions filtered and/or boosted by some criteria. For example, you want to suggest song titles filtered by certain artists or you want to boost song titles based on their genre.

To achieve suggestion filtering and/or boosting, you can add context mappings while configuring a completion field. You can define multiple context mappings for a completion field. Every context mapping has a unique name and a type. There are two types: category and geo. Context mappings are configured under the contexts parameter in the field mapping.
大致意思就是:completion suggester会考虑索引中的所有文档,但有些情况下我们希望在复合一定的过滤条件的范围内获得suggest。

为了实现过滤或增强suggest,您可以在配置completion字段的mapping时添加上context mappings。可以为completion字段定义多个上context mappings。每个context mappings都有唯一的name和type。有两种type:category【类型】 和 geo【地理位置】。上下文映射在字段映射中的contexts参数下配置。

DELETE place
PUT place
{"mappings": {"properties": {"suggest": {"type": "completion","contexts": [{"name": "place_type","type": "category"},{"name": "location","type": "geo","precision": 4}]}}}
}
  • 加入数据
# 添加数据并且指定对应的context数据
PUT place/_doc/1
{"suggest": {"input": [ "timmy's", "starbucks", "dunkin donuts" ],"contexts": {"place_type": [ "cafe", "food" ]                    }}
}
PUT place/_doc/2
{"suggest": {"input": [ "monkey", "timmy's", "Lamborghini" ],"contexts": {"place_type": [ "money"]                    }}
}PUT place/_doc/3
{"suggest": {"input": "timmy's","contexts": {"location": [{"lat": 43.6624803,"lon": -79.3863353},{"lat": 43.6624718,"lon": -79.3873227}]}}
}
  • 查询演示
# 1、通过近似地位坐标经纬度进行推荐查推荐
POST place/_search
{"suggest": {"place_suggestion": {"prefix": "tim","completion": {"field": "suggest","size": 10,"contexts": {"location": {"lat": 43.662,"lon": -79.380}}}}}
}# 2、通过 contexts 过滤掉部分不需要智能推荐的数据
GET place/_search
{"suggest": {"my_place_suggest": {"text": "star","completion": {"field": "suggest","size":10,"contexts":{"place_type": [ "cafe", "restaurants" ]  }}}}
}# 3、使用 上文进行查询并且指定按照指定boot指定的内容进行排序
GET place/_search
{"suggest": {"my_suggest": {"text": "timmy","completion": {"field": "suggest","size": 10,"contexts": {"place_type": [{"context": "money"},{"context": "food","boost":2}]}}}}
}
  • 查询结果
# 1、通过近似地位坐标经纬度进行推荐查推荐
{"took": 1,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 0,"relation": "eq"},"max_score": null,"hits": []},"suggest": {"place_suggestion": [{"text": "tim","offset": 0,"length": 3,"options": [{"text": "timmy's","_index": "place","_id": "3","_score": 1,"_source": {"suggest": {"input": "timmy's","contexts": {"location": [{"lat": 43.6624803,"lon": -79.3863353},{"lat": 43.6624718,"lon": -79.3873227}]}}},"contexts": {"location": ["dpz8"]}}]}]}
}# 2、通过 contexts 过滤掉部分不需要智能推荐的数据
{"took": 0,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 0,"relation": "eq"},"max_score": null,"hits": []},"suggest": {"my_place_suggest": [{"text": "star","offset": 0,"length": 4,"options": [{"text": "starbucks","_index": "place","_id": "1","_score": 1,"_source": {"suggest": {"input": ["timmy's","starbucks","dunkin donuts"],"contexts": {"place_type": ["cafe","food"]}}},"contexts": {"place_type": ["cafe"]}}]}]}
}# 3、使用 上文进行查询并且指定按照指定boot指定的内容进行排序
{"took": 0,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 0,"relation": "eq"},"max_score": null,"hits": []},"suggest": {"my_suggest": [{"text": "timmy","offset": 0,"length": 5,"options": [{"text": "timmy's","_index": "place","_id": "1","_score": 2,"_source": {"suggest": {"input": ["timmy's","starbucks","dunkin donuts"],"contexts": {"place_type": ["cafe","food"]}}},"contexts": {"place_type": ["food"]}},{"text": "timmy's","_index": "place","_id": "2","_score": 1,"_source": {"suggest": {"input": ["monkey","timmy's","Lamborghini"],"contexts": {"place_type": ["money"]}}},"contexts": {"place_type": ["money"]}}]}]}
}

同样 Context Suggester 也可以在同一个document中设置多个context例如:

DELETE place_path_category
PUT place_path_category
{"mappings": {"properties": {"suggest": {"type": "completion","contexts": [{"name": "place_type","type": "category","path": "cat"},{"name": "location","type": "geo","precision": 4,"path": "loc"}]},"loc": {"type": "geo_point"}}}
}
  • 添加数据
PUT place_path_category/_doc/1
{"suggest": ["timmy's","starbucks","dunkin donuts"],"cat": ["cafe","food"],"loc": [{"lat": 43.6624803,"lon": -79.3863353}]
}PUT place_path_category/_doc/2
{"suggest": ["linked's", "snow city", "seven eleven"],"cat": ["fast food", "shop"],"loc": [{"lat": 49.6624803,"lon": -65.3863353}]
}
  • 关联查询
# 通过 path 进行关联
POST place_path_category/_search?pretty
{"suggest": {"place_suggestion": {"prefix": "link","completion": {"field": "suggest","contexts": {"place_type": [                             { "context": "fast food" }]}}}}
  • 查询结果
{"took": 0,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 0,"relation": "eq"},"max_score": null,"hits": []},"suggest": {"place_suggestion": [{"text": "link","offset": 0,"length": 4,"options": [{"text": "linked's","_index": "place_path_category","_id": "2","_score": 1,"_source": {"suggest": ["linked's","snow city","seven eleven"],"cat": ["fast food","shop"],"loc": [{"lat": 49.6624803,"lon": -65.3863353}]},"contexts": {"place_type": ["fast food"]}}]}]}
}

【Elasticsearch】 (搜索引擎如何做搜索推荐?) Elasticsearch中 使用 Suggesters 推荐查询相关推荐

  1. Elasticsearch:从零开始到搜索 - 使用 Elasticsearch 摄取管道玩转你的数据

    在本文中,我想快速了解 Elasticsearch 提供的一个(众多)有趣的功能,我也倾向于在生产设置中使用它,即 Ingest Pipelines. 此功能允许在实际文档索引发生之前预处理文档. 听 ...

  2. php操作ElasticSearch搜索引擎流程详解

    更多python.php教程请到友情连接: 菜鸟教程https://www.piaodoo.com 茂名一技http://www.enechn.com ppt制作教程步骤 http://www.tpy ...

  3. ElasticSearch探索之路(一)初识ElasticSearch:特点、应用场景、架构设计、基本概念

    文章目录 什么是ElasticSearch? Lucene ELK Elasticsearch的特点 应用场景 架构设计 基本概念 文档 类型 索引 什么是ElasticSearch? Elastic ...

  4. 左右互搏:GAN在爱奇艺短视频推荐冷启动中的实践

    导语:由于推荐系统冷启动问题的存在,在视频推荐中为用户推荐新视频是一个极具挑战的问题,新视频推荐的效果直接影响推荐系统"新陈代谢"的稳定性和内容生态的健康发展.为了解决该问题,本文 ...

  5. ElasticSearch搜索引擎详解-持续更新中

    ElasticSearch搜索引擎详解 1. ElasticSearch概述 1.1 elasticsearch是什么 1.2 全文搜索引擎 1.3 elasticsearch and solr 1. ...

  6. 一文详解 | 开放搜索兼容Elasticsearch做召回引擎

    简介:开放搜索发布开源兼容版,支持阿里云Elasticsearch做搜索召回引擎,本文详细介绍阿里云ES用户如何通过接入开放搜索兼容版丰富行业分词库,提升查询语义理解能力,无需开发.算法投入,即可获得 ...

  7. elasticsearch实现博客搜索_(eblog)9、博客搜索引擎开发、后台精选

    小Hub领读: 继续我们的eblog,今天来完成博客的搜索引擎,数据同步,后台精选哈! 项目名称:eblog 项目 Git 仓库:https://github.com/MarkerHub/eblog( ...

  8. elasticsearch 6.2.2 搜索推荐系列(三)之高级搜索查询实现( 中文+拼音+首字母+简繁转换+特殊符号过滤)

    一.先摆需求: 1.中文搜索.英文搜索.中英混搜   如:"南京东路","cafe 南京东路店" 2.全拼搜索.首字母搜索.中文+全拼.中文+首字母混搜   如 ...

  9. 搜索引擎|全文搜索技术Elasticsearch

    总结搜索引擎技术的知识归纳,工作中用到过 ES,以此拓展知识面. 文章目录 1 全文检索技术 2 倒排索引 3 ES及其优点 4 ES术语及其概念 5 ES对外提供的接口形式 6 索引 7 映射 8 ...

  10. 【实战】PHP如何使用 ElasticSearch 做搜索

    ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作为Apach ...

最新文章

  1. 使用 PHP 构建的 Web 应用如何避免 XSS 攻击
  2. C语言函数集(十三)
  3. python 获取文件大小,创建时间和访问时间
  4. 带着问题学 Kubernetes 架构!
  5. 微软BI 之SSIS 系列 - MVP 们也不解的 Scrip Task 脚本任务中的一个 Bug
  6. [html] iframe在更改了src之后,不出现后退或者前进按钮怎么解决?
  7. js菜单自适应的实现
  8. python3 re正则匹配数据获取案例
  9. 爬虫:Python爬虫学习笔记之Urllib库
  10. 两道CTF Reverse题目(windows平台)
  11. 步进电机基础(5.9)-步进电机的驱动与控制-三相步进电机的驱动电路
  12. Linux运维(指令全)
  13. JZOJ 幽幽子与森林
  14. 编译可在Android上运行的依赖库(二):gettext库
  15. 分析三种近场通信技术的特点及对未来近场通信技术的应用场景进行分析与预测
  16. (附源码)计算机毕业设计ssm黑河市劳务人员管理系统
  17. 【报错】部署portainer可视化工具报错
  18. 一岁半小朋友的火星电话和滑滑梯
  19. PHP+mysql 入门级通讯录(一)
  20. 世界地球日 | 成功解锁首件烤仔时尚单品

热门文章

  1. 完善保密加密机制(Perfectly-secret Encryption)——无条件安全加密算法
  2. 通过路由器来设置局域网下无线打印机打印
  3. php魔方阵,利用C语言玩转魔方阵实例教程
  4. matlab处理声音报告,基于MATLAB的语音信号分析与处理的实验报告.doc
  5. 数组基础知识 (一)
  6. 直通车点击率、点击率、创意图、关键词、出价卡位,提升直通车点击率的技巧和方法
  7. 以数据为中心的路由协议_腰部零售企业如何以数据中台为中心,加速数字化落地...
  8. 计算机如何去除桌面名称阴影,电脑界面上图标下面的名字上有阴影怎么去掉
  9. 青光眼 程序员_青光眼-如何不失明:让我们谈谈治疗方法…
  10. windows性能监控Perfmon