standard prices google flexible engine costs app google-app-engine go google-cloud-datastore

google-app-engine - flexible - google cloud app engine prices



Cómo filtrar una consulta GAE? (1)

El (primer) problema es este:

q := datastore.NewQuery("employee") q.Filter("Name =", "Andrew W")

Query.Filter() devuelve una consulta derivada con el filtro que especificó incluido. Debe almacenar el valor de retorno y usarlo en curso:

q := datastore.NewQuery("employee") q = q.Filter("Name =", "Andrew W")

O solo una linea

q := datastore.NewQuery("employee").Filter("Name =", "Andrew W")

Nota: Sin esto, la consulta que ejecute no tendrá filtros y, por lo tanto, devolverá todas las entidades previamente guardadas del tipo "employee" , donde "Joe Citizen" podría ser el primero que vea impreso.

Para la primera ejecución, lo más probable es que veas 0 resultados. Tenga en cuenta que, dado que no utiliza consultas Ancestor, se aplica una coherencia final . El SDK de desarrollo simula el almacén de datos de alta replicación con su consistencia eventual, y por lo tanto, la consulta que sigue a las operaciones Put() no verá los resultados.

Si pone un poco de time.Sleep() antes de continuar con la consulta, verá los resultados que espera:

time.Sleep(time.Second) var e2 Employee q := datastore.NewQuery("employee").Filter("Name=", "Andrew W") // Rest of your code...

También tenga en cuenta que al ejecutar su código en el SDK puede simular una gran coherencia al crear su contexto de esta manera:

c, err := aetest.NewContext(&aetest.Options{StronglyConsistentDatastore: true})

Pero, por supuesto, esto es solo para fines de prueba, no puede hacer esto en producción.

Si desea obtener resultados consistentes, especifique una clave ancestra al crear la clave y use consultas ancestrales . Una clave antecesor solo es necesaria si desea resultados muy consistentes. Si está bien con unos segundos de retraso para que aparezcan los resultados, no es necesario. También tenga en cuenta que la clave antecesor no tiene que ser la clave de una entidad existente, es solo semántica. Puedes crear cualquier clave ficticia. Usar la misma clave (ficticia) para entidades múltiples los colocará en el mismo grupo de entidades y las consultas de ancestros en este grupo serán muy consistentes.

A menudo, la clave antecesor es una clave existente, generalmente derivada del usuario o cuenta actual, porque puede crearse / computarse fácilmente y almacena / almacena cierta información adicional, pero como se indicó anteriormente, no tiene que ser así.

Intento guardar dos registros y luego obtener el segundo. El problema es que el filtro no parece funcionar. Aunque filtro por nombre ("Andrew W") siempre obtengo "Joe Citizen". El contador también indica 2 registros cuando debería ser solo uno. Esto me vuelve loco. Vea el código completo a continuación. El resultado imprime el counter 2 e2 {"Joe Citizen" "Manager" "2015-03-24 09:08:58.363929 +0000 UTC" ""}

package main import ( "fmt" "time" "net/http" "google.golang.org/appengine" "google.golang.org/appengine/datastore" ) type Employee struct { Name string Role string HireDate time.Time Account string } func init(){ http.HandleFunc("/", handle) } func handle(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) e1 := Employee{ Name: "Joe Citizen", Role: "Manager", HireDate: time.Now(), } _, err := datastore.Put(c, datastore.NewKey(c, "employee", "", 0, nil), &e1) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) panic(err) return } e1.Name = "Andrew W" _, err = datastore.Put(c, datastore.NewKey(c, "employee", "", 0, nil), &e1) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) panic(err) return } var e2 Employee q := datastore.NewQuery("employee") q.Filter("Name =", "Andrew W") cnt, err := q.Count(c) if err !=nil{ http.Error(w, err.Error(), http.StatusInternalServerError) panic(err) return } for t := q.Run(c); ; { if _, err := t.Next(&e2); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) panic(err) return } break } fmt.Fprintf(w, "counter %v e2 %q", cnt, e2) }