2013-01-12 22 views
5

Sembra che dovrebbe essere una domanda facile. Ma non sembra che lo the docs risponda. Usando l'esempio da loro, voglio fare questo:ndb Ricerca corrispondenza stringa parziale

Account.query(Account.title == "best") 

Tranne che voglio uguagliare anche le stringhe parziali. Quindi, in questo scenario:

acct = Account(title="the best account in the world") 

una query NDB con l'argomento "migliore" sarebbe partita la acct.

L'unica opzione che vedo al momento è quella di passare attraverso Account.query() e abbinare ogni title con il modulo re.search in python. Questa non sembra una buona soluzione.

Aggiornamento: Sto anche guardando gql. In questo modo:

acct = ndb.gql('SELECT * from Account WHERE title LIKE '%best%') 

restituisce un Parse Error: Invalid WHERE Condition at symbol LIKE

+0

GQL non è SQL. –

risposta

7

GQL non ha i caratteri jolly di corrispondenza, per ottenere che sarà necessario utilizzare il full text search.

3

Per un campo (presumibilmente) breve come un titolo, aggiungendo una StringProperty ripetuta che contiene ciascuna parola del titolo (ignorando le parole di arresto, forse) consentirebbe di abbinare le parole e sarebbe più semplice dell'utilizzo dell'API di ricerca .

+1

è quella pratica comune? Sembra un trucco. – mehulkar

+0

wow .. davvero sorpreso da questa risposta .. :-( – CIF

+0

Non l'ho implementato da solo, anche se ho visto suggerito altri posti (mi dispiace, non ho un link) – Trevor

5

NOTA: Questo non risponde esattamente alla domanda, ma chi cerca inizia potrebbe trovare utile questa risposta.

Il campo di stringa NDB è indicizzato in modo da poter eseguire una ricerca maggiore di (>=) e minore di (<). Supponendo che il Person seguente modello:

class Person(ndb.Model): 
    name   = ndb.StringProperty() 
    name_lower = ndb.ComputedProperty(lambda self: self.name.lower()) 

È possibile effettuare le seguenti operazioni:

def search_by_text(text): 
    text = text.lower() 
    limit = text[:-1] + chr(ord(text[-1]) + 1) 
    return Person.query(Person.name_lower >= text, Person.name_lower < limit).fetch(50) 

p = search_by_text('kri') 

La variabile limit in questo esempio conterrà la stringa 'KRJ' e diventa il limite dei valori di ricerca. Quanto sopra vi porterà tutte le persone il cui nome è maggiore di kri ma inferiore a krj e limite ai primi 50 risultati. A causa del limite, i nomi come kross e lark verranno filtrati.

Nota: è importante disporre di ndb.ComputedProperty per contenere una versione minuscola del campo su cui si desidera effettuare la ricerca. Non dimenticare di aggiungere quello!

+0

Questa è la soluzione migliore I potrebbe trovare una semplice ricerca di corrispondenza parziale delle stringhe senza la necessità di implementare la ricerca full-text. – werm098

Problemi correlati