2012-10-15 23 views
12

Utilizzo dello GAE search API è possibile cercare una corrispondenza parziale?API di ricerca GAE di corrispondenza parziale

Sto tentando di creare funzionalità di completamento automatico in cui il termine sarebbe una parola parziale. per esempio.

> b
> Bui
> costruire

sarebbero tutti di ritorno "edificio".

Com'è possibile con GAE?

risposta

27

Anche se l'istruzione LIKE (corrispondenza parziale) non è supportata nella ricerca di testo completo, ma è possibile modificarla.

In primo luogo, tokenize la stringa di dati per tutte le possibili stringhe (ciao = h, egli, Hel, ecco, ecc)

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 

costruire un indice + documento (Search API) utilizzando le stringhe tokenized

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) 

Eseguire la ricerca e 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

Questo metodo funziona bene. Sono riuscito a modare la funzione search.index di Ferris per tokenizzare automaticamente tutti i campi di testo (un cambio di riga), e "funziona". Basta non cercare di visualizzare detto campo per un utente direttamente dal risultato della ricerca;) –

+1

Ho anche aggiunto 'name.lower()' perché ho avuto alcuni strani problemi con la lingua russa: se un gettone inizia con una lettera maiuscola Non ero in grado di trovare un tale segno. –

+8

nota amichevole: la frase è "voilà!" –

0

Ho lo stesso problema per il controllo typeahead, e la mia soluzione è stringa Analizza per piccola parte:

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 

Spero che questo aiuto

2

proprio come @Desmond Lua risposta , ma con diversa funzione di token:

 
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) 

analizzerà hello world come he,hel,hell,hello,wo,wor,worl,world.

è un bene per scopi di completamento automatico luce

0

La mia versione ottimizzata: non ripetere gettoni

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

Si prega di aggiungere ulteriori descrizione per quanto riguarda la risposta inviato signore. –

Problemi correlati