API поиска GAE с частичным соответствием

Используя API поиска GAE, можно ли найти частичное совпадение?

Я пытаюсь создать функциональность автозаполнения, где термин будет частичным словом. например.

> б
> буи
> построить

все бы вернулось "здание".

Как это возможно с GAE?

5 ответов

Решение

Хотя оператор 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, но с другой функцией токенизации:

def tokenize (word):
  маркер =[]
  words = word.split(' ')
  для слов в словах:
    для я в диапазоне (лен (слово)):
      если я ==0: продолжить
      w = word [i]
      если я ==1: 
        маркер + = [слово [0]+ W]
        Продолжить

      маркер + = [лексема [-1:][0]+ W]

  return ",".join(токен)

это будет разбирать hello world как he,hel,hell,hello,wo,wor,worl,world,

это хорошо для легкой цели автозаполнения

Как описано в полнотекстовом поиске и операторе LIKE, нет, это невозможно, поскольку в API поиска реализована полнотекстовая индексация.

Надеюсь это поможет!

Моя версия оптимизирована: не повторять токены

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

У меня та же проблема для управления 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

Надеюсь это поможет

Другие вопросы по тегам