Используя API поиска GAE, можно найти частичное совпадение?
Я пытаюсь создать функциональность автозаполнения, где термин будет частичным словом. например.
> b
> bui
> build
все вернут "здание".
Как это возможно с GAE?
Используя API поиска GAE, можно найти частичное совпадение?
Я пытаюсь создать функциональность автозаполнения, где термин будет частичным словом. например.
> b
> bui
> build
все вернут "здание".
Как это возможно с GAE?
Хотя оператор LIKE (частичное совпадение) не поддерживается в полнотекстовом поиске, но вы можете его обойти.
Во-первых, токенизируйте строку данных для всех возможных подстрок (hello = h, he, hel, lo и т.д.)
def tokenize_autocomplete(phrase):
a = []
for word in phrase.split():
j = 1
while True:
for i in range(len(word) - j + 1):
a.append(word[i:i + j])
if j == len(word):
break
j += 1
return a
Создайте индекс + документ (Search API), используя токенизированные строки
index = search.Index(name='item_autocomplete')
for item in items: # item = ndb.model
name = ','.join(tokenize_autocomplete(item.name))
document = search.Document(
doc_id=item.key.urlsafe(),
fields=[search.TextField(name='name', value=name)])
index.put(document)
Выполните поиск, и вах!
results = search.Index(name="item_autocomplete").search("name:elo")
https://code.luasoftware.com/tutorials/google-app-engine/partial-search-on-gae-with-search-api/
так же, как @Desmond Lua, но с другой функцией tokenize:
def tokenize(word): token=[] words = word.split(' ') for word in words: for i in range(len(word)): if i==0: continue w = word[i] if i==1: token+=[word[0]+w] continue token+=[token[-1:][0]+w] return ",".join(token)
он проанализирует hello world
как he,hel,hell,hello,wo,wor,worl,world
.
Это хорошо для легкой цели автозаполнения
Как описано в Полном текстовом поиске и заявлении LIKE, это невозможно, так как API поиска реализует полнотекстовую индексацию.
Надеюсь, это поможет!
У меня такая же проблема для управления typeahead, и мое решение представляет собой строку синтаксического анализа для небольшой части:
name='hello world'
name_search = ' '.join([name[:i] for i in xrange(2, len(name)+1)])
print name_search;
# -> he hel hell hello hello hello w hello wo hello wor hello worl hello world
Надеемся на эту помощь
Моя версия оптимизирована: не повторяйте токены
def tokenization(text):
a = []
min = 3
words = text.split()
for word in words:
if len(word) > min:
for i in range(min, len(word)):
token = word[0:i]
if token not in a:
a.append(token)
return a
Прыгать очень поздно здесь.
Но вот моя хорошо документированная функция, которая делает токенизацию. Строка документации должна помочь вам понять это и использовать его. Удачи!!!
def tokenize(string_to_tokenize, token_min_length=2):
"""Tokenizes a given string.
Note: If a word in the string to tokenize is less then
the minimum length of the token, then the word is added to the list
of tokens and skipped from further processing.
Avoids duplicate tokens by using a set to save the tokens.
Example usage:
tokens = tokenize('pack my box', 3)
Args:
string_to_tokenize: str, the string we need to tokenize.
Example: 'pack my box'.
min_length: int, the minimum length we want for a token.
Example: 3.
Returns:
set, containng the tokenized strings. Example: set(['box', 'pac', 'my',
'pack'])
"""
tokens = set()
token_min_length = token_min_length or 1
for word in string_to_tokenize.split(' '):
if len(word) <= token_min_length:
tokens.add(word)
else:
for i in range(token_min_length, len(word) + 1):
tokens.add(word[:i])
return tokens