12

使用 google appengine 数据存储,有没有办法执行 gql 查询,该查询在不区分大小写的 StringProperty 数据类型上指定 WHERE 子句?我并不总是确定该值的大小写。文档指定我的值在哪里区分大小写,有没有办法使它不敏感?

例如 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

我认为数据存储区中没有这样的操作员。

你控制类别数据的输入吗?如果是这样,您应该选择一种规范的形式来存储它(全部小写或全部大写)。如果您出于某种原因需要存储原始案例,那么您可以只存储两列——一列是原始的,一列是标准化的。这样你就可以做一个普通的 WHERE 子句。

于 2009-11-01T21:50:50.910 回答
6

数据存储不支持不区分大小写的比较,因为您无法索引使用它们的查询(除非使用转换值的索引)。正如彼得建议的那样,除了标准版本之外,解决方案是存储字符串的规范化版本。AETycoon库中的属性类可能会很有帮助,尤其是 DerivedProperty。

于 2009-11-02T10:08:13.787 回答
0

这个线程很有帮助,让我想用类似的方法做出贡献,使部分搜索匹配成为可能。我在数据存储类型上再添加一个字段,并将标准化短语上的每个单词保存为一组,然后使用 IN 过滤器进行碰撞。这是一个使用 Clojure 的示例。规范化部分至少应该很容易翻译成java(感谢@raek on #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])]))))))
于 2011-05-24T07:35:10.270 回答