StringProperty 的 gql 查询中不区分大小写的 where 子句

发布于 2024-08-09 19:54:59 字数 825 浏览 5 评论 0原文

使用 google appengine 数据存储区,是否有一种方法可以执行 gql 查询,该查询在不区分大小写的 StringProperty 数据类型上指定 WHERE 子句?我并不总是确定值的大小写。文档指定 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

Using the google appengine datastore, is there a way to perform a gql query that specifies a WHERE clause on a StringProperty datatype that is case insensitive? I am not always sure what case the value will be in. The docs specify that the where is case sensitive for my values, is there a way to make this insensitive?

for instance the db Model would be this:

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

and the data looks like this:

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

i would like to say

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

and have returnvalue contain

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

空气里的味道 2024-08-16 19:54:59

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

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

I don't think there is an operator like that in the datastore.

Do you control the input of the category data? If so, you should choose a canonical form to store it in (all lowercase or all uppercase). If you need to store the original case for some reason, then you could just store two columns - one with the original, one with the standardized one. That way you can do a normal WHERE clause.

丑疤怪 2024-08-16 19:54:59

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

The datastore doesn't support case insensitive comparisons, because you can't index queries that use them (barring an index that transforms values). The solution is to store a normalized version of your string in addition to the standard one, as Peter suggests. The property classes in the AETycoon library may prove helpful, in particular, DerivedProperty.

那小子欠揍 2024-08-16 19:54:59

该线程很有帮助,让我想用类似的方法做出贡献,以使部分搜索匹配成为可能。我在数据存储类型上添加了一个字段,并将标准化短语上的每个单词保存为一组,然后使用 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])]))))))

This thread was helpful and makes me want to contribute with similar approach to make partial search match possible. I add one more field on datastore kind and save each word on normalized phrase as a set and then use IN filter to collide. This is an example with a Clojure. Normalize part should easy translate to java at least (thanks to @raek on #clojure), while database interaction should be convertable to any language:

(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])]))))))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文