我正在尝试使用elasticsearch_dsl
python 库设置 ElasticSearch 。我已经能够设置索引,并且能够使用该.filter()
方法进行搜索,但是我无法使该.suggest
方法起作用。
我正在尝试使用completion
映射类型和suggest
查询方法,因为这将用于自动完成字段(在弹性文档中推荐)。
我是弹性的新手,所以我猜我错过了一些东西。任何指导将不胜感激!
我没有找到一个教程,有正是我想要的,但我通过对ElasticSearch.com和文档阅读elasticsearch_dsl,在一些例子看这里和这里
PS:我在 Heroku 上使用 Searchbox Elasticsearch
# imports [...]
edge_ngram_analyzer = analyzer(
'edge_ngram_analyzer',
type='custom',
tokenizer='standard',
filter=[
'lowercase',
token_filter(
'edge_ngram_filter', type='edgeNGram',
min_gram=1, max_gram=20
)
]
)
class DocumentIndex(ElasticDocument):
title = Text()
title_suggest = Completion(
analyzer=edge_ngram_analyzer,
)
class Index:
name = 'documents-index'
# [...] Initialize index
# [...] Upload Documents (5,000 documents)
# DocumentIndex.init()
# [DocumentIndex(**doc).save() for doc in mydocs]
这是 Web 控制台中显示的映射:
{
"documents-index": {
"mappings": {
"doc": {
"properties": {
"title": {
"type": "text"
},
"title_suggest": {
"type": "completion",
"analyzer": "edge_ngram_analyzer",
"search_analyzer": "standard",
"preserve_separators": true,
"preserve_position_increments": true,
"max_input_length": 50
}
}
}
}
}
}
验证索引是否存在:
>>> search = Search(index='documents-index')
>>> search.count() # Returns correct amount of documents
5000
>>> [doc for doc in search.scan()][:3]
>>> [<Hit(documents-index/doc/1): ...} ...
测试搜索 - 作品:
>>> query = search.filter('match', title='class')
>>> query.execute()
>>> result.hits
<Response: [<Hit(documents-in [ ... ]
>>> len(result.hits)
10
>>> query.to_dict() # see query payload
{
"query":{
"bool":{
"filter":[
{
"fuzzy":{
"title":"class"
}
}
]
}
}
}
我无法让任何.suggest()
方法起作用。注意:*我正在关注官方图书馆文档
测试建议:
>>> query = search.suggest(
'title-suggestions',
'class',
completion={
'field': 'title_suggest',
'fuzzy': True
})
>>> query.execute()
<Response: {}>
>>> query.to_dict() # see query payload
{
"suggest": {
"title-suggestions": {
"text": "class",
"completion": { "field": "title_suggest" }
}
}
}
我也尝试了下面的代码,显然有许多不同类型的查询和值,但结果是相似的。(注意.filter()
我总是得到预期的结果)。
>>> query = search.suggest(
'title-suggestions',
'class',
term=dict(field='title'))
>>> query.to_dict() # see query payload
{
"suggest": {
"title-suggestions": {
"text": "class",
"term": {
"field": "title"
}
}
}
}
>>> query.execute()
<Response: {}>
根据 Honza 的建议,我将title_suggest
映射更新为仅完成,没有自定义分析器。我也删除了索引并从头开始重新索引
class DocumentIndex(ElasticDocument):
title = Text()
title_suggest = Completion()
class Index:
name = 'documents-index'
不幸的是,问题仍然存在。这里还有一些测试:
title_suggest
是否正确编入索引>>> search = Search(index='documents-index)
>>> search.index('documents-index').count()
23369
>>> [d for d in search.scan()][0].title
'AnalyticalGrid Property'
>>> [d for d in search.scan()][0].title_suggest
'AnalyticalGrid Property'
>>> len(search.filter('term', title='class').execute().hits)
10
>>> search.filter('term', title_suggest='Class').execute().hits
[]
>>> search.suggest('suggestions', 'class', completion={'field':
'title_suggest'}).execute().hits
[]
>>> pprint(index.get_mapping())
{
"documents-index": {
"mappings": {
"doc": {
"properties": {
"title": { "type": "text" },
"title_suggest": {
"analyzer": "simple",
"max_input_length": 50,
"preserve_position_increments": True,
"preserve_separators": True,
"type": "completion"
}
}
}
}
}
}
我想将 Honza 提供的解决方案正式化为另一个答案的评论之一。
问题不在于映射,而在于.suggest()
方法的结果不在hits
.
这些建议现在在由以下返回的字典中可见:
>>> response = query.execute()
>>> print(response)
<Response: {}>
>>> response.to_dict()
# output is
# {'query': {},
# 'suggest': {'title-suggestions': {'completion': {'field': 'title_suggest'},
# [...]
我还发现了有关此github 问题的其他详细信息:
HonzaKral 评论于 27 天前
Response 对象提供对elasticsearch 返回的任何和所有字段的访问。为方便起见,有一个快捷方式允许迭代命中,因为这是最常见的,也很容易做到。对于响应的其他部分,例如聚合或建议,您需要像 response.suggest.foo.options 一样显式访问它们。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句