2009-11-01 2 views
11

Sử dụng kho dữ liệu appengine của google, có cách nào để thực hiện truy vấn gql chỉ định mệnh đề WHERE trên kiểu dữ liệu StringProperty không phân biệt chữ hoa chữ thường không? Tôi không phải luôn luôn chắc chắn trường hợp giá trị sẽ được in Các tài liệu xác định rằng nơi là trường hợp nhạy cảm với các giá trị của tôi, là có một cách để làm cho điều này không nhạy cảm?Trường hợp không phân biệt mệnh đề where trong truy vấn gql cho StringProperty

ví dụ db mẫu sẽ là:

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

và các dữ liệu trông như thế này:

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

tôi muốn nói

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

và có returnvalue chứa

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

Trả lời

13

Tôi không nghĩ rằng có một toán tử như vậy trong kho dữ liệu.

Bạn có kiểm soát dữ liệu nhập của dữ liệu danh mục không? Nếu vậy, bạn nên chọn một biểu mẫu chuẩn để lưu trữ nó trong (tất cả chữ thường hoặc tất cả chữ hoa). Nếu bạn cần lưu trữ trường hợp ban đầu vì một số lý do, thì bạn chỉ có thể lưu trữ hai cột - một cột với cột gốc, một cột có cột chuẩn. Bằng cách đó bạn có thể làm một mệnh đề WHERE bình thường.

5

Kho dữ liệu không hỗ trợ so sánh phân biệt chữ hoa chữ thường, vì bạn không thể lập chỉ mục truy vấn sử dụng chúng (chặn chỉ mục biến đổi giá trị). Giải pháp là để lưu trữ một phiên bản chuẩn của chuỗi của bạn ngoài một tiêu chuẩn, như Peter cho thấy. Các lớp thuộc tính trong thư viện AETycoon có thể hữu ích, đặc biệt là DerivedProperty.

+0

tôi đã kết thúc viết một kịch bản để bình thường hóa chúng. Cảm ơn con trỏ đến thư viện. – jasonmw

0

Chuỗi này hữu ích và làm cho tôi muốn đóng góp với cách tiếp cận tương tự để thực hiện tìm kiếm một phần phù hợp nhất có thể. Tôi thêm một trường nữa vào loại kho dữ liệu và lưu từng từ trên cụm từ bình thường hóa thành một tập hợp và sau đó sử dụng bộ lọc IN để va chạm. Đây là một ví dụ với Clojure. Bình thường hóa một phần nên dễ dàng dịch để java ít nhất (nhờ @raek trên #clojure), trong khi tương tác cơ sở dữ liệu nên có gì chuyển thành ngôn ngữ nào:

(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])]))))))