Нечувствительность к регистру, где предложение в gql-запросе для StringProperty
Используя хранилище данных google appengine, существует ли способ выполнить запрос gql, который указывает предложение WHERE в типе данных StringProperty, который нечувствителен к регистру? Я не всегда уверен, в каком случае будет значение. Документы указывают, что где чувствителен регистр для моих значений, есть ли способ сделать это нечувствительным?
например, 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
Ответы
Ответ 1
Я не думаю, что в хранилище данных есть такой оператор.
Вы контролируете ввод данных категории? Если это так, вы должны выбрать каноническую форму для ее хранения (все строчные или все заглавные). Если вам по какой-то причине нужно хранить исходный код, вы можете просто сохранить два столбца - один с оригиналом, один со стандартным. Таким образом вы можете сделать нормальное предложение WHERE.
Ответ 2
Хранилище данных не поддерживает сравнение, нечувствительное к регистру, поскольку вы не можете индексировать запросы, которые их используют (запрет индекса, который преобразует значения). Решение заключается в том, чтобы сохранить нормализованную версию вашей строки в дополнение к стандартной, как предлагает Питер. Классы свойств в библиотеке AETycoon могут оказаться полезными, в частности, DerivedProperty.
Ответ 3
Этот поток был полезен и заставляет меня хотеть внести свой вклад в подобный подход, чтобы сделать возможное частичное совпадение. Я добавляю еще одно поле в виде хранилища данных и сохраняю каждое слово в нормализованной фразе как набор, а затем использую фильтр 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])]))))))