Нечувствительно к регистру, где предложение в запросе gql для StringProperty

StackOverflow https://stackoverflow.com/questions/1658163

  •  11-09-2019
  •  | 
  •  

Вопрос

Есть ли способ выполнить запрос gql, в котором указано предложение WHERE для типа данных StringProperty, не чувствительного к регистру, с помощью хранилища данных Google Appengine?Я не всегда уверен, в каком случае будет значение.В документах указано, что для моих значений учитывается регистр, есть ли способ сделать это нечувствительным?

например, модель БД будет такой:

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
Это было полезно?

Решение

Я не думаю, что в хранилище данных есть такой оператор.

Контролируете ли вы ввод данных категории?Если это так, вам следует выбрать каноническую форму для его хранения (все строчные или все прописные буквы).Если вам по каким-то причинам необходимо сохранить исходный случай, то вы можете просто сохранить два столбца — один с исходным, другой со стандартизированным.Таким образом, вы можете использовать обычное предложение WHERE.

Другие советы

Хранилище данных не поддерживает сравнения без учета регистра, поскольку вы не можете индексировать запросы, которые их используют (за исключением индекса, преобразующего значения).Решение состоит в том, чтобы хранить нормализованную версию вашей строки в дополнение к стандартной, как предлагает Питер.Классы недвижимости в AETycoon может оказаться полезной библиотека, в частности DerivedProperty.

Эта тема была полезной, и я захотел внести свой вклад, применив аналогичный подход, чтобы сделать возможным частичное совпадение поиска.Я добавляю еще одно поле типа хранилища данных и сохраняю каждое слово в нормализованной фразе как набор, а затем использую 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])]))))))
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top