2009-11-01 11 views
11

Al utilizar el almacén de datos appengine de google, ¿hay alguna forma de realizar una consulta gql que especifique una cláusula WHERE en un tipo de datos StringProperty que no distinga entre mayúsculas y minúsculas? No estoy seguro de en qué caso va a estar el valor. Los documentos especifican que el where distingue entre mayúsculas y minúsculas para mis valores, ¿hay alguna manera de hacer esto insensible?Casilla insensible a mayúsculas y minúsculas en la consulta gql para StringProperty

por ejemplo, el modelo DB sería la siguiente:

from google.appengine.ext import db 
class Product(db.Model): 
    id = db.IntegerProperty() 
    category = db.StringProperty() 

y los datos se parece a esto:

id   category 
=================== 
1   cat1 
2   cat2 
3   Cat1 
4   CAT1 
5   CAT3 
6   Cat4 
7   CaT1 
8   CAT5 

me gustaría decir

gqlstring = "WHERE category = '{0}'".format('cat1') 
returnvalue = Product.gql(gqlstring) 

y tienen returnvalue contienen

id   category 
=================== 
1   cat1 
3   Cat1 
4   CAT1 
7   CaT1 

Respuesta

13

No creo que haya un operador así en el almacén de datos.

¿Controla la entrada de los datos de categoría? Si es así, debe elegir una forma canónica para almacenarlo (todo en minúsculas o mayúsculas). Si necesita guardar el estuche original por alguna razón, entonces puede almacenar dos columnas, una con la original y la otra con la estándar. De esa forma puedes hacer una cláusula WHERE normal.

5

El almacén de datos no es compatible con las comparaciones insensibles a mayúsculas y minúsculas, ya que no puede indexar las consultas que las utilizan (salvo un índice que transforma los valores). La solución es almacenar una versión normalizada de su cadena, además de la estándar, como sugiere Peter. Las clases de propiedad en la biblioteca AETycoon pueden resultar útiles, en particular, DerivedProperty.

+0

que no terminan de escribir un guión para normalizarlos. Gracias por el puntero a la biblioteca. – jasonmw

0

Este tema fue útil y me dan ganas de contribuir con un enfoque similar para hacer posible una búsqueda parcial. Agrego un campo más en el tipo de almacén de datos y guardo cada palabra en la frase normalizada como un conjunto y luego uso el filtro IN para colisionar. Este es un ejemplo con Clojure. Normalizar la parte fácil debería traducirse a Java al menos (gracias a @raek en #clojure), mientras que la interacción de base de datos debe ser convertible a cualquier idioma:

(use '[clojure.contrib.string :only [split lower-case]]) 
(use '[appengine-magic.services.datastore :as ds]) 

; initialize datastore kind entity 
(ds/defentity AnswerTextfield [value, nvalue, avalue]) 

; normalize and lowercase a string 
(defn normalize [string-to-normalize] 
    (lower-case 
    (apply str 
     (remove #(= (Character/getType %) Character/NON_SPACING_MARK) 
       (java.text.Normalizer/normalize string-to-normalize java.text.Normalizer$Form/NFKD))))) 

; save original value, normalized value and splitted normalized value 
(defn textfield-save! [value] 
    (ds/save! 
    (let [nvalue (normalize value)] 
     (ds/new* AnswerTextfield [value nvalue (split #" " nvalue)])))) 

; normalized search 
(defn search-normalized [value] 
    (ds/query :kind AnswerTextfield 
      :filter [(= :nvalue (normalize value))])) 

; partial normalized word search 
(defn search-partial [value] 
    (flatten 
    (let [coll []] 
     (for [splitted-value (split #" " (normalize value))] 
     (merge coll 
      (ds/query :kind AnswerTextfield 
        :filter [(in :avalue [splitted-value])])))))) 
Cuestiones relacionadas