2012-10-15 17 views
12

Czy można wyszukać dopasowanie częściowe?Częściowe pasujące wyszukiwanie GAE API

Próbuję utworzyć funkcję autouzupełniania, w której termin byłby częściowym słowem. na przykład.

> b
> Bui
> budować

by wszystko zwrot "budynek".

Jak to jest możliwe z GAE?

Odpowiedz

27

Chociaż instrukcja LIKE (dopasowanie częściowe) nie jest obsługiwana w wyszukiwaniu pełnotekstowym, ale można ją zhakować.

Najpierw tokenize ciąg danych dla wszystkich możliwych podciągów (cześć = h, on, hel, lo, itp)

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 

tworzenia indeksu + dokument (Search API), używając tokenized ciągi

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) 

Wykonuj wyszukiwanie, a walah!

results = search.Index(name="item_autocomplete").search("name:elo") 

https://code.luasoftware.com/tutorials/google-app-engine/partial-search-on-gae-with-search-api/

+0

To działa dobrze. Udało mi się zmodyfikować funkcję search.index Ferrisa, aby automatycznie tokenizować wszystkie pola tekstowe (jedna zmiana linii) i "po prostu działa". Po prostu nie próbuj wyświetlać tego pola do użytkownika bezpośrednio z wyniku wyszukiwania;) –

+1

Dodałem także 'name.lower()' ponieważ miałem pewne dziwne problemy z językiem rosyjskim: jeśli token zaczyna się od dużej litery Nie mogłem znaleźć takiego żetonu. –

+8

przyjazna uwaga: fraza to "voila!" –

0

mam ten sam problem do kontroli wpisywanie znaków z wyprzedzeniem, a moje rozwiązanie jest parse ciąg na małe części:

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 

Nadzieja to pomóc

2

jak @Desmond Lua odpowiedź , ale z inną funkcją tokenizacji:

 
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) 

to będzie parsować hello world jako he,hel,hell,hello,wo,wor,worl,world.

to jest dobre dla celów światło autouzupełniania

0

Moja wersja zoptymalizowana: nie powtórzyć tokeny

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 
+0

Proszę dodać więcej informacji dotyczących wysłanej odpowiedzi sir. –