Подтвердить что ты не робот

Частичное сопоставление API поиска GAE

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

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

> b
> bui
> build

все вернут "здание".

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

4b9b3361

Ответ 1

Хотя оператор 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/

Ответ 2

так же, как @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.

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

Ответ 4

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

Надеемся на эту помощь

Ответ 5

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

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

Ответ 6

Прыгать очень поздно здесь.

Но вот моя хорошо документированная функция, которая делает токенизацию. Строка документации должна помочь вам понять это и использовать его. Удачи!!!

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