Question

Utilisation du datastore AppEngine de Google, est-il un moyen d'effectuer une requête gql qui spécifie une clause WHERE sur un type de StringProperty qui est insensible à la casse? Je ne suis pas toujours sûr de ce cas, la valeur sera. Les documents précisent que le cas où est sensible pour mes valeurs, est-il un moyen de rendre cette insensible?

, par exemple, le modèle db serait ceci:

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

et les données ressemble à ceci:

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

Je voudrais dire

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

et ont returnvalue contenir

id         category
===================
1          cat1
3          Cat1
4          CAT1
7          CaT1
Était-ce utile?

La solution

Je ne pense pas qu'il y ait un opérateur comme ça dans le magasin de données.

Avez-vous de contrôler l'entrée des données de catégorie? Si oui, vous devez choisir une forme canonique pour la stocker dans (tout en minuscules ou en majuscules). Si vous devez stocker le cas d'origine pour une raison quelconque, alors vous pouvez stocker deux colonnes - un avec l'original, l'un avec celui standardisé. De cette façon, vous pouvez faire une clause normale WHERE.

Autres conseils

Le datastore ne supporte pas les cas des comparaisons insensibles, parce que vous ne pouvez pas les requêtes d'index qui les utilisent (sauf un index qui transforme les valeurs). La solution est de stocker une version normalisée de votre chaîne en plus d'une norme, comme le suggère Peter. Les classes de propriété dans la bibliothèque AETycoon peut se révéler utile, en particulier DerivedProperty.

Ce fil a été utile et me donne envie de contribuer à l'approche similaire pour faire correspondre la recherche partielle possible. J'ajouter un champ sur genre et enregistrer datastore chaque mot sur la phrase normalisée comme un ensemble et ensuite utiliser dans le filtre à entrer en collision. Ceci est un exemple avec un Clojure. Normaliser partie devrait facilement se traduire par au moins java (grâce à @raek sur #clojure), alors que l'interaction de base de données devrait être à convertable une langue:

(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])]))))))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top