2009-11-01 68 views
11

使用google appengine數據存儲,是否有一種方法可以執行gql查詢,該查詢指定不區分大小寫的StringProperty數據類型上的WHERE子句?我並不總是知道價值會在什麼情況下發生。文檔指出我的價值觀在哪裏區分大小寫,是否有辦法讓這種感覺不敏感?不區分大小寫忽略StringProperty的gql查詢中的where子句

例如數據庫模型應該是這樣的:

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 

回答

13

我不認爲在數據存儲中有這樣的操作符。

您是否控制類別數據的輸入?如果是這樣,你應該選擇一個規範形式來存儲它(全部小寫或全部大寫)。如果您因某種原因需要保存原始案例,那麼您可以只保存兩列 - 一個與原始案例,一個與標準案例。這樣你可以做一個正常的WHERE子句。

5

數據存儲區不支持不區分大小寫的比較,因爲您無法爲使用它們的查詢編制索引(禁止轉換值的索引)。正如彼得所建議的,解決方案是存儲標準化版本的字符串。 AETycoon庫中的屬性類可能證明是有幫助的,特別是DerivedProperty。

+0

我沒有寫出來的腳本正常化他們。感謝指向圖書館的指針。 – jasonmw 2009-11-02 16:41:39

0

此主題是有幫助的,並使我想用類似的方法貢獻部分搜索匹配成爲可能。我在數據存儲類中再添加一個字段,並將每個單詞作爲一個集合保存在規範化的短語中,然後使用IN過濾器進行衝突。這是一個Clojure的例子。規範化部分應易於轉換爲Java至少(感謝@raek上#clojure),而數據庫的交互應該是可轉化爲任何語言:

(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])]))))))