代码之家  ›  专栏  ›  技术社区  ›  jasonmw

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

  •  11
  • jasonmw  · 技术社区  · 16 年前

    例如,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
    
    3 回复  |  直到 16 年前
        1
  •  14
  •   Peter Recore    16 年前

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

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

        2
  •  6
  •   Nick Johnson    16 年前

    数据存储不支持不区分大小写的比较,因为您不能为使用它们的查询编制索引(除非索引转换值)。正如Peter所建议的,解决方案是在标准字符串之外存储字符串的规范化版本。中的属性类 AETycoon

        3
  •  0
  •   MarkokraM    14 年前

    这个帖子很有帮助,让我想用类似的方法来实现部分搜索匹配。我在DatastoreKind上再添加一个字段,并将规范化短语上的每个单词保存为一个集合,然后在过滤器中使用以进行碰撞。这是一个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])]))))))