字符串属性的 gql 查询中不区分大小写的 where 子句

Posted

技术标签:

【中文标题】字符串属性的 gql 查询中不区分大小写的 where 子句【英文标题】:Case insensitive where clause in gql query for StringProperty 【发布时间】:2010-12-12 02:30:39 【问题描述】:

使用 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

【问题讨论】:

【参考方案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])]))))))

【讨论】:

【参考方案2】:

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

【讨论】:

我最终写了一个脚本来规范它们。感谢您指向图书馆。【参考方案3】:

我认为数据存储区中没有这样的运算符。

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

【讨论】:

以上是关于字符串属性的 gql 查询中不区分大小写的 where 子句的主要内容,如果未能解决你的问题,请参考以下文章

SQL语句中模糊查询中不区分大小写怎么写?如:select × from table where number like‘%PK%’

JavaScript中不区分大小写的字符串替换?

如何grep文件中不区分大小写的字符串?

Go中不区分大小写的字符串比较

Mongo中不区分大小写的搜索

Django中不区分大小写的字段