2013-01-12 7 views
5

Dies scheint wie es eine einfache Frage sein sollte. Aber the docs scheint nicht zu antworten. Unter Verwendung des Beispiels von ihnen möchte ich dies tun:ndb Abfrage Teilzeichenfolge

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

Außer ich möchte auch Teilstrings übereinstimmen. So in diesem Szenario:

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

eine ndb Abfrage mit dem Argument "beste" würde die acct entsprechen.

Die einzige Option, die ich im Moment sehe, ist durch Account.query() zu durchlaufen und jedes title mit re.search Modul in Python zu verbinden. Dies scheint keine gute Lösung zu sein.

Update: Ich sehe auch gql. dies zu tun:

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

gibt ein Parse Error: Invalid WHERE Condition at symbol LIKE

+0

GQL ist nicht SQL. –

Antwort

7

GQL keine Platzhalter hat übereinstimmt, zu erreichen, dass Sie die full text search verwenden müssen.

3

Für ein (vermutlich) kurzes Feld wie einen Titel, würde das Hinzufügen einer wiederholten StringProperty, die jedes Wort des Titels enthält (unter Berücksichtigung von Stoppwörtern, vielleicht), eine Übereinstimmung mit Wörtern ermöglichen und wäre einfacher als die Verwendung der Such-API .

+1

ist das übliche Praxis? Scheint wie ein Hack. – mehulkar

+0

wow .. wirklich überrascht mit dieser antwort .. :-( – CIF

+0

Ich habe das selbst nicht implementiert, obwohl ich es anderen Orten empfohlen habe (Entschuldigung, ich habe keinen Link). – Trevor

5

HINWEIS: Dies beantwortet die Frage nicht genau, aber jemand, nach dem Sie suchen, könnte diese Antwort nützlich finden.

Das String-Feld von NDB ist so indiziert, dass Sie mehr als (>=) und weniger als (<) suchen können. Unter der Annahme der folgenden Person Modell:

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

Sie tun können, die folgenden:

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') 

Die limit Variable in diesem Beispiel die Zeichenfolge enthält ‚KRJ‘ und wird die Grenze der Suchwerte. Die oben genannten erhalten Sie alle Personen, deren Name größer als kri aber weniger als krj ist und auf die ersten 50 Ergebnisse begrenzen. Wegen des Limits werden Namen wie kross und lark herausgefiltert.

Hinweis: Es ist wichtig, dass Sie eine ndb.ComputedProperty haben, die eine Kleinschreibung des Felds enthält, nach dem Sie suchen möchten. Vergessen Sie nicht, das hinzuzufügen!

+0

Dies ist die beste Lösung, die ich könnte für eine einfache Suche nach partiellen Zeichenfolgen suchen, ohne die Volltextsuche implementieren zu müssen. – werm098