Skip to content

Commit

Permalink
Add search_as_you_type datatype
Browse files Browse the repository at this point in the history
  • Loading branch information
Diego Giovane Pasqualin authored and honzakral committed Feb 3, 2020
1 parent 7651c9d commit e881fc1
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
8 changes: 8 additions & 0 deletions elasticsearch_dsl/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,14 @@ class Text(Field):
}
name = 'text'

class SearchAsYouType(Field):
_param_defs = {
'analyzer': {'type': 'analyzer'},
'search_analyzer': {'type': 'analyzer'},
'search_quote_analyzer': {'type': 'analyzer'},
}
name = 'search_as_you_type'

class Keyword(Field):
_param_defs = {
'fields': {'type': 'field', 'hash': True},
Expand Down
79 changes: 79 additions & 0 deletions examples/search_as_you_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# -*- coding: utf-8 -*-
"""
Example ``Document`` with search_as_you_type field datatype and how to search it.
When creating a field with search_as_you_type datatype ElasticSearch creates additional subfields to enable efficient
as-you-type completion, matching terms at any position within the input.
To custom analyzer with ascii folding allow search to work in different languages.
"""
from __future__ import print_function, unicode_literals

from elasticsearch_dsl import connections, Document, analyzer, token_filter, SearchAsYouType
from elasticsearch_dsl.query import MultiMatch

# custom analyzer for names
ascii_fold = analyzer(
'ascii_fold',
# we don't want to split O'Brian or Toulouse-Lautrec
tokenizer='whitespace',
filter=[
'lowercase',
token_filter('ascii_fold', 'asciifolding')
]
)


class Person(Document):
name = SearchAsYouType(max_shingle_size=3)

class Index:
name = 'test-search-as-you-type'
settings = {
'number_of_shards': 1,
'number_of_replicas': 0
}


if __name__ == '__main__':
# initiate the default connection to elasticsearch
connections.create_connection()

# create the empty index
Person.init()

import pprint
pprint.pprint(Person().to_dict(), indent=2)

# index some sample data
names = [
'Andy Warhol',
'Alphonse Mucha',
'Henri de Toulouse-Lautrec',
'Jára Cimrman',
]
for id, name in enumerate(names):
Person(_id=id, name=name).save()

# refresh index manually to make changes live
Person._index.refresh()

# run some suggestions
for text in ('já', 'Cimr', 'toulouse', 'Henri Tou', 'a'):
s = Person.search()

s.query = MultiMatch(
query=text,
type="bool_prefix",
fields=[
"name",
"name._2gram",
"name._3gram"
]
)

response = s.execute()

# print out all the options we got
for h in response:
print('%15s: %25s' % (text, h.name))

1 comment on commit e881fc1

@xiffy
Copy link

@xiffy xiffy commented on e881fc1 Feb 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love this,

Just when I was thinking of filing a feature request for the search_as_you_type-type I when saw the latest merge.
Thanks a lot!

Please sign in to comment.