Domanda

Uso della appengine datastore google, c'è un modo per eseguire una query GQL che specifica una clausola WHERE su un tipo di dati StringProperty che è case insensitive? Io non sono sempre sicuro di quello che caso il valore sarà in. I documenti indicano che la dove è case sensitive per i miei valori, c'è un modo per rendere questo insensibile?

per esempio il Modello db sarebbe questo:

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

ed i dati si presenta così:

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

vorrei dire

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

e hanno returnvalue contenere

id         category
===================
1          cat1
3          Cat1
4          CAT1
7          CaT1
È stato utile?

Soluzione

Non credo che ci sia un operatore come quello nel datastore.

si fa a controllare l'input dei dati categoria? Se è così, si dovrebbe scegliere una forma canonica di conservarlo in (tutto minuscolo o tutto in maiuscolo). Se avete bisogno di memorizzare il caso originale per qualche motivo, allora si può solo memorizzare due colonne - uno con l'originale, uno con quella standardizzata. In questo modo si può fare un normale clausola WHERE.

Altri suggerimenti

L'archivio dati non supporta caso paragoni insensibili, perché non si può query indice che li utilizzano (salvo un indice che trasforma i valori). La soluzione è quella di memorizzare una versione normalizzata della stringa in aggiunta a quella standard, come suggerisce Peter. Le classi di proprietà in AETycoon biblioteca possono rivelarsi utile, in particolare, DerivedProperty.

Questo thread è stato utile e fa venire voglia di contribuire con approccio simile per rendere possibile parziale partita di ricerca. Aggiungo un altro campo in genere datastore e salvare ogni parola sulla frase normalizzato come un insieme e poi l'uso in filtri a collidere. Questo è un esempio di un Clojure. Normalizzare parte dovrebbe facile tradurre in java almeno (grazie alla @raek su #clojure), mentre l'interazione del database dovrebbe essere convertibile in qualsiasi lingua:

(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])]))))))
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top