12

google appengineデータストアを使用して、大文字と小文字を区別しないStringPropertyデータ型でWHERE句を指定するgqlクエリを実行する方法はありますか?値がどのような場合になるかは常にわかりません。ドキュメントでは、値の大文字と小文字が区別される場所が指定されていますが、これを区別しないようにする方法はありますか?

たとえば、dbモデルは次のようになります。

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

データは次のようになります。

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

言いたい

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

returnvalue含まれています

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

3 に答える 3

14

データストアにそのような演算子はないと思います。

カテゴリデータの入力を管理していますか? その場合は、正規の形式を選択して保存する必要があります (すべて小文字またはすべて大文字)。何らかの理由で元のケースを保存する必要がある場合は、2 つの列を保存するだけで済みます。1 つは元のケース、もう 1 つは標準化されたケースです。そうすれば、通常の WHERE 句を実行できます。

于 2009-11-01T21:50:50.910 に答える
6

データストアは、大文字と小文字を区別しない比較をサポートしていません。これは、それらを使用するクエリにインデックスを付けることができないためです (値を変換するインデックスを除く)。解決策は、Peter が提案するように、標準の文字列に加えて、文字列の正規化されたバージョンを保存することです。AETycoonライブラリのプロパティ クラス、特に DerivedProperty が役立つ場合があります。

于 2009-11-02T10:08:13.787 に答える
0

このスレッドは役に立ち、部分検索の一致を可能にする同様のアプローチで貢献したいと思いました。データストアの種類にもう 1 つのフィールドを追加し、正規化されたフレーズの各単語をセットとして保存し、IN フィルターを使用して衝突させます。これは Clojure を使用した例です。正規化部分は、少なくとも Java に簡単に変換できるはずですが (#clojure の @raek に感謝)、データベースとのやり取りは任意の言語に変換できる必要があります。

(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])]))))))
于 2011-05-24T07:35:10.270 に答える