Im trying to setup ElasticSearch using the elasticsearch_dsl
python library. I have been able to setup the Index, and I am able to search using the .filter()
method, but I cannot get the .suggest
method to work.
I am trying to use the completion
mapping type, and the suggest
query method since this is going to be used for an autocomplete field (recommended on elastic's docs).
I am new to elastic, so I am guessing I am missing something. Any guidance will be greatly appreciated!
What I have done so far
I did not find a tutorial that had exactly what I wanted, but I read through the documentation on ElasticSearch.com and elasticsearch_dsl, and looked at some examples hereand here
PS: I am using Searchbox Elasticsearch on Heroku
Index / Mappings Setup:
# 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]
Mappings Output:
This is the mapping as shown in the web console:
{
"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
}
}
}
}
}
}
Attempting to Search
Verify Index exists:
>>> 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): ...} ...
Test Search - Works:
>>> 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"
}
}
]
}
}
}
The part that fails
I cannot get any of the .suggest()
methods to work.
Note:
* I am following the official library docs
Test 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" }
}
}
}
I also tried the code below, and obviously many different types of queries and values, but the results were similar. (note with .filter()
I always get the expected result).
>>> 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: {}>
Update
Per Honza's suggestion, I updated the title_suggest
mapping to be only Completion, with no custom analyzers. I also deleted the index and reindexed from scratch
class DocumentIndex(ElasticDocument):
title = Text()
title_suggest = Completion()
class Index:
name = 'documents-index'
Unfortunately, the problem remains. Here are some more tests:
Verify title_suggest
is being indexed properly
>>> 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'
Tried searching again:
>>> 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
[]
Verify Mapping:
>>> 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"
}
}
}
}
}
}