2016-08-08 61 views
1

Wenn ich keinen Filter verwende, bekomme ich Ergebnisse. Wenn ich einen Filter verwende (dieser Datensatz existiert definitiv), bekomme ich keine Ergebnisse. Es könnte das Fehlen eines Index sein, der für diese Eigenschaft definiert ist, aber, wie ich es verstehe, sollten einfache Indizes auf dem Entwicklungsserver erstellt werden (und eine index.yaml-Datei erstellt und mit dieser gefüllt werden). Das passiert nicht.AppEngine Datastore Abfrage mit Filter gibt nie Ergebnisse (Go)

query = datastore.NewQuery("UserAccount").Filter("email =", "[email protected]") 

ua := UserAccount{} 
t := query.Run(ctx) 
for ; ; { 
    if _, err = t.Next(&ua); err == nil { 
     log.Debugf(ctx, "Current: %s", ua) 
    } else if err == datastore.Done { 
     break 
    } else { 
     panic(err) 
    } 
} 

Wenn der Entwicklungs-Server beendet wird, heißt es, dass es „Speichern von Suchindizes“ ist:

INFO  2016-08-08 05:09:52,894 api_server.py:651] Saving search indexes 

Da jedoch ein „index.yaml“ Datei nicht erscheint, gehe ich davon aus, dass es mussten keine Indizes erstellt werden, was bedeutet, dass meine Anfrage nicht die gewünschte Wirkung hatte?

Was fehlt mir?

Edit:

Beachten Sie, dass der Datensatz zuvor erstellt wurde und die Anwendung gestartet und gestoppt, da viele Male. Ich bezweifle ernsthaft, dass dies eine Konsequenz ist.

Edit 2:

Zum Zweck der Prüfung habe ich das folgende Modell mit dem folgenden Code erstellt. Beide zeigen das gleiche Verhalten wie mein ursprüngliches Modell und Code.

Definition:

type TestEntity struct { 
    Email string 
} 

Code:

log.Debugf(ctx, "Putting.") 

email := "[email protected]" 

te := &TestEntity{ 
     Email: email, 
} 

k := datastore.NewKey(ctx, "TestEntity", "123", 0, nil) 
_, err = datastore.Put(ctx, k, te) 
if err != nil { 
    panic(err) 
} 

log.Debugf(ctx, "Waiting.") 
time.Sleep(1 * time.Second) 

query := datastore.NewQuery("TestEntity") 

var results []TestEntity 
_, err = query.GetAll(ctx, &results) 
log.Debugf(ctx, "GetAll: %s", results) 

log.Debugf(ctx, "Running query.") 

query = datastore.NewQuery("TestEntity").Filter("email =", email) 

te = &TestEntity{} 
t := query.Run(ctx) 
for ; ; { 
    if _, err = t.Next(te); err == nil { 
     log.Debugf(ctx, "Found: [%s]", te.Email) 
    } else if err == datastore.Done { 
     log.Debugf(ctx, "Done.") 
     break 
    } else { 
     panic(err) 
    } 
} 

Ergebnisse:

2016/08/09 02:11:36 DEBUG: Putting. 
2016/08/09 02:11:36 DEBUG: Waiting. 
2016/08/09 02:11:37 DEBUG: GetAll: [{[email protected]}] 
2016/08/09 02:11:37 DEBUG: Running query. 
2016/08/09 02:11:37 DEBUG: Done. 

Screenshot von Viewer:

Screenshot of Viewer

+0

Es ist wegen ** eventueller Konsistenz **. Siehe mögliche Duplikate: 1. [Wie filtere ich eine GAE-Abfrage?] (Http://stackoverflow.com/questions/29228712/how-to-filter-a-gae-query); 2. [Google App Engine-Datenspeicher - Testing Queries schlägt fehl] (http://stackoverflow.com/questions/28590519/google-app-engine-datastore-testing-queries-fails); 3. [Warum liefert die Abfrage keine Ergebnisse, wenn der Vorgänger nicht bereitgestellt wird?] (Http://stackoverflow.com/questions/29529296/why-the-query-doesn-return-results-when-the-ancestor- is-not-provided) – icza

+0

Bitte bestätigen Sie, wenn dies Ihr Problem löst. – icza

+0

@icza Es tut es nicht. Der Datensatz existierte vorher (gelesen: bevor der aktuelle Entwicklungsserver gestartet wurde). Es wurde nicht nur erstellt. –

Antwort

3

Der Eigenschaftsname in dem Datenspeicher ist "Email" mit Kapital E, nicht "email".

Es ist fallempfindlich ist, muss mit einem Kapital E abgefragt werden:

query = datastore.NewQuery("UserAccount").Filter("Email =", "[email protected]") 

Wenn Sie es mit kleinen e gespeichert/abgerufen werden mögen, können Sie tags nutzen, um die Zuordnung zu tun, zum Beispiel:

type UserAccount struct { 
    Email string `datastore:"email"` 
    // other fields... 
} 
+0

Danke, dass Sie etwas bemerkt haben, dass ich zu dumm war, um mich selbst zu bemerken. Das war eine lustige dreißig Nachrichten. Zumindest haben wir die Möglichkeit geschaffen, das "nicht indizierte" Ding zu sehen. Auch habe ich Ergebnisse, aber ich sehe immer noch keine Indizes im Admin oder eine "index.yaml" -Datei. Wie bereits von DanCornilescu erwähnt, dürfen einfache Indizes niemals dargestellt werden (was es anscheinend schwieriger macht, Kostenschätzungen für Schreibvorgänge zu berechnen). Zu guter Letzt, als ich meine AppEngine-Version unter Go ("goapp serve") ausführte, habe ich eine Fußnote erhalten, die besagt, dass der Python Dev-Server umgebrochen wird. –

+0

@DustinOprea Nur Composite-Indizes müssen zu "index.yaml" hinzugefügt werden. Einzelne Immobilienindizes nicht. Einzelne Eigenschaftsindizes existieren auf einer _pertity_ Basis: eine Entität kann eine indizierte Eigenschaft "Email" haben, eine andere kann eine nicht indizierte Eigenschaft "Email" haben, eine dritte darf nicht einmal eine solche Eigenschaft haben. Und sogar ein 4. kann einen haben, aber einen anderen Typ ... Datenspeicher ist keine relationale Datenbank, es ist schemalos. – icza

+0

@DustinOprea Und ja, das Go-SDK verwendet den Python-Dev-Server, es ist kein Geheimnis. – icza

0

Um eine Entität im Ergebnis einer Abfrage/eines Filters durch eine Eigenschaft zu finden, muss die Eigenschaft (in der Modelldefinition) zum Zeitpunkt der Erstellung der Entität und der Hintergrundindizierung des Datenspeichers aktiviert sein Aufgabe (n) muss dafür erledigt werden.

Wenn Sie ermöglichen die Indizierung für diese Eigenschaft nach das Unternehmen erstellt wurde, müssen Sie die Eigenschaft neu zu schreiben, so dass die Indizierung Aufgaben ausgelöst werden dafür finden Sie unter: https://stackoverflow.com/a/34583510/4495081.

Die Meldung "Suchindexe speichern" ist eine generische Nachricht, die vor dem Vorgang gedruckt wurde. Dies bedeutet nicht, dass das Ergebnis der Operation nicht leer ist.

Sie müssen sich keine Sorgen machen, dass Ihre index.yaml Datei leer ist. Nicht alle Indizes müssen in der index.yaml-Datei vorhanden sein, nur die komplexeren müssen sie enthalten. Ihr Filter kann mithilfe der integrierten Indizes angepasst werden (nachdem die oben genannten Indizierungsanforderungen erfüllt sind).Von Indexes:

Es gibt zwei Arten von Indizes:

  • integrierten Indizes

    standardmäßig automatisch Cloud Datastor vorgibt, einen Index für jede Eigenschaft jeder Einheit Art. Diese einzelnen Eigenschaftsindizes sind , die für einfache Abfragetypen geeignet sind.

  • Composite-Indizes

    Composite-Indizes Index mehrere Eigenschaftswerte pro indizierte Einheit. Zusammengesetzte Indizes unterstützen komplexe Abfragen und sind in einer Indexkonfigurationsdatei (index.yaml) definiert.

+0

Es ist nicht klar, wie Eigenschaften für die Indexierung gekennzeichnet werden oder ob sie sogar unterstützt werden. In der Dokumentation wird das Tagging nur im Zusammenhang mit dem * Vorbeugen * eines Indexes erwähnt: (https://cloud.google.com/appengine/docs/go/datastore/indexes) "Age int' datastore: ", noindex" '" –

+0

In der Tat , scheint in dieser Hinsicht anders als Python zu sein.Die Antwort gilt immer noch - Sie könnten die Indizierung deaktiviert haben, als die Entität erstellt wurde :) –

+0

@DustinOprea: Sie können sehen, ob eine Eigenschaft in Ihrem Cloud Console Datastore Viewer indiziert ist. Suchen Sie eine Entität und klicken Sie auf das Bearbeitungssymbol - es werden alle Eigenschaften angezeigt. –