使用google appengine数据存储区,有没有办法执行gql查询,在不区分大小写的StringProperty数据类型上指定WHERE子句?我并不总是确定该值的大小写。文档指定where对我的值区分大小写,是否有办法使这种不敏感?
例如db Model就是这样:
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
答案 0 :(得分:14)
我认为数据存储区中没有这样的运营商。
您是否控制类别数据的输入?如果是这样,您应该选择一个规范形式来存储它(全部小写或全部大写)。如果由于某种原因需要存储原始案例,那么您可以只存储两列 - 一列是原始列,另一列是标准列。这样你就可以做一个普通的WHERE子句。
答案 1 :(得分:6)
数据存储区不支持不区分大小写的比较,因为您无法索引使用它们的查询(禁止转换值的索引)。彼得建议,除了标准版本之外,解决方案是存储字符串的标准化版本。 AETycoon库中的属性类可能会有所帮助,尤其是DerivedProperty。
答案 2 :(得分: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])]))))))