Google App Engine: Có thể thực hiện truy vấn Gql THÍCH không?


123

Đơn giản thực sự. Trong SQL, nếu tôi muốn tìm kiếm một trường văn bản cho một vài ký tự, tôi có thể làm:

SELECT blah FROM blah WHERE blah LIKE '%text%'

Tài liệu về App Engine không đề cập đến cách đạt được điều này, nhưng chắc chắn đó là một vấn đề đủ phổ biến?


3
Vấn đề tiếp tục xoay quanh những người đang cố gắng sử dụng GAE Datastore như thể nó là một cơ sở dữ liệu quan hệ / ~ SQL. Bằng cách Google giới thiệu GQL, nó tiếp tục khiến mọi người suy nghĩ về các hệ thống SQL. Tuy nhiên, tôi hiểu rằng Google đang cố gắng thực hiện quá trình chuyển đổi cho mọi người dễ dàng hơn nhiều mặc dù tôi không chắc đây là cách tiếp cận phù hợp.
fuentesjr

Câu trả lời:


81

BigTable, là phần cuối cơ sở dữ liệu cho Máy ứng dụng, sẽ mở rộng tới hàng triệu bản ghi. Do đó, App Engine sẽ không cho phép bạn thực hiện bất kỳ truy vấn nào dẫn đến việc quét bảng, vì hiệu suất sẽ rất khủng khiếp đối với một bảng được phổ biến tốt.

Nói cách khác, mọi truy vấn phải sử dụng một chỉ mục. Đây là lý do tại sao bạn chỉ có thể làm =, ><truy vấn. (Trên thực tế bạn cũng có thể làm !=nhưng API thực hiện việc này bằng cách sử dụng kết hợp ><truy vấn.) Đây cũng là lý do tại sao môi trường phát triển giám sát tất cả các truy vấn bạn làm và tự động thêm bất kỳ chỉ mục bị thiếu nào vào index.yamltệp của bạn .

Không có cách nào để lập chỉ mục cho một LIKEtruy vấn vì vậy đơn giản là nó không có sẵn.

Hãy theo dõi phiên Google IO này để được giải thích rõ hơn và chi tiết hơn về vấn đề này.


77

Tôi đang đối mặt với cùng một vấn đề, nhưng tôi đã tìm thấy một cái gì đó trên các trang của công cụ ứng dụng google:

Mẹo: Bộ lọc truy vấn không có cách rõ ràng để chỉ khớp một phần của giá trị chuỗi, nhưng bạn có thể giả mạo kết hợp tiền tố bằng bộ lọc bất đẳng thức:

db.GqlQuery("SELECT * FROM MyModel WHERE prop >= :1 AND prop < :2",
            "abc",
            u"abc" + u"\ufffd")

Điều này khớp với mọi thực thể MyModel với prop thuộc tính chuỗi bắt đầu bằng ký tự abc. Chuỗi unicode u "\ ufffd" đại diện cho ký tự Unicode lớn nhất có thể. Khi các giá trị thuộc tính được sắp xếp trong một chỉ mục, các giá trị nằm trong phạm vi này là tất cả các giá trị bắt đầu bằng tiền tố đã cho.

http://code.google.com.vn/appengine/docs/python/datastore/queriesandindexes.html

có lẽ điều này có thể làm nên mánh khóe;)


6
+1 Tho đáng để chỉ ra đây là trường hợp nhạy cảm. May mắn thay, dữ liệu trong trường tôi đang truy vấn được chuyển đổi thành chữ thường trước khi lưu trữ.
Cuga

12

Altough App Engine không hỗ trợ các truy vấn THÍCH, hãy xem các thuộc tính ListPropertyStringListProperty . Khi kiểm tra tính bằng được thực hiện trên các thuộc tính này, thử nghiệm sẽ thực sự được áp dụng cho tất cả các thành viên trong danh sách, ví dụ: list_property = valuekiểm tra nếu giá trị xuất hiện ở bất kỳ đâu trong danh sách.

Đôi khi tính năng này có thể được sử dụng như một cách giải quyết cho việc thiếu các truy vấn THÍCH. Ví dụ, nó có thể thực hiện tìm kiếm văn bản đơn giản, như được mô tả trên bài đăng này .


3
bài đăng không còn tồn tại nữa
mwm

9

Bạn cần sử dụng dịch vụ tìm kiếm để thực hiện các truy vấn tìm kiếm toàn văn tương tự như SQL LIKE.

Gaelyk cung cấp ngôn ngữ cụ thể cho tên miền để thực hiện các truy vấn tìm kiếm thân thiện hơn với người dùng . Ví dụ: đoạn trích sau sẽ tìm thấy mười cuốn sách đầu tiên được sắp xếp từ những cuốn mới nhất có tiêu đề chứa fern và thể loại khớp chính xác thriller:

def documents = search.search {
    select all from books
    sort desc by published, SearchApiLimits.MINIMUM_DATE_VALUE
    where title =~ 'fern'
    and genre =  'thriller'
    limit 10
}

Like được viết dưới dạng toán tử khớp Groovy =~. Nó hỗ trợ các chức năng như distance(geopoint(lat, lon), location)là tốt.



3

Hãy xem Objectify ở đây , nó giống như một API truy cập Datastore. Có một câu hỏi thường gặp với câu hỏi này cụ thể, đây là câu trả lời

Làm cách nào để tôi thực hiện một truy vấn tương tự (THÍCH "foo%")
Bạn có thể làm một cái gì đó như startWith hoặc endWith nếu bạn đảo ngược thứ tự khi được lưu trữ và tìm kiếm. Bạn thực hiện một truy vấn phạm vi với giá trị bắt đầu bạn muốn và một giá trị ngay phía trên giá trị bạn muốn.

String start = "foo";
    ... = ofy.query(MyEntity.class).filter("field >=", start).filter("field <", start + "\uFFFD");

1
nó sẽ tìm kiếm "bắt đầu bằng" chứ không phải "Chứa".
Hardik Patel

1

Chỉ cần theo dõi tại đây: init.py # 354 "> http://code.google.com.vn/p/googlzonengine/source/browse/trunk/python/google/appengine/ext/search/ init .py # 354

Nó hoạt động!

class Article(search.SearchableModel):
    text = db.TextProperty()
    ...

  article = Article(text=...)
  article.save()

To search the full text index, use the SearchableModel.all() method to get an
instance of SearchableModel.Query, which subclasses db.Query. Use its search()
method to provide a search query, in addition to any other filters or sort
orders, e.g.:

  query = article.all().search('a search query').filter(...).order(...)

1

Tôi đã thử nghiệm điều này với API Java cấp thấp GAE Datastore. Tôi và làm việc hoàn hảo

    Query q = new Query(Directorio.class.getSimpleName());

    Filter filterNombreGreater = new FilterPredicate("nombre", FilterOperator.GREATER_THAN_OR_EQUAL, query);
    Filter filterNombreLess = new FilterPredicate("nombre", FilterOperator.LESS_THAN, query+"\uFFFD");
    Filter filterNombre =  CompositeFilterOperator.and(filterNombreGreater, filterNombreLess);

    q.setFilter(filter);

1
cái này hoạt động với tiền tố, nhưng nếu tôi muốn khớp từ cuối chuỗi thì sao? Ví dụ: tôi muốn tìm kiếm abc trong sdfdsabc, sau đó nó sẽ trả về sdfdsabc
user1930106

1

Nói chung, mặc dù đây là một bài viết cũ, một cách để tạo ra một 'THÍCH' hoặc 'ILIKE' là thu thập tất cả các kết quả từ truy vấn '> =', sau đó lặp lại kết quả bằng python (hoặc Java) cho các phần tử chứa những gì bạn chứa 'Đang tìm kiếm.

Giả sử bạn muốn lọc người dùng đã cho aq = 'luigi'

users = []
qry = self.user_model.query(ndb.OR(self.user_model.name >= q.lower(),self.user_model.email >= q.lower(),self.user_model.username >= q.lower()))

for _qry in qry:
 if q.lower() in _qry.name.lower() or q.lower() in _qry.email.lower() or q.lower() in _qry.username.lower():
      users.append(_qry)

1

Không thể thực hiện tìm kiếm THÍCH trên công cụ ứng dụng kho dữ liệu, bao giờ việc tạo một Arraylist sẽ thực hiện thủ thuật nếu bạn cần tìm kiếm một từ trong chuỗi.

@Index
    public ArrayList<String> searchName;

và sau đó để tìm kiếm trong chỉ mục bằng cách sử dụng objectify.

List<Profiles> list1 = ofy().load().type(Profiles.class).filter("searchName =",search).list();

và điều này sẽ cung cấp cho bạn một danh sách với tất cả các mục có chứa thế giới bạn đã thực hiện trên tìm kiếm


0

Nếu LIKE '%text%'luôn luôn so sánh với một từ hoặc một vài (nghĩ về hoán vị) và dữ liệu của bạn thay đổi chậm (từ từ có nghĩa là nó không quá đắt - cả về giá cả và khôn ngoan về hiệu suất - để tạo và cập nhật chỉ mục) thì Thực thể chỉ số quan hệ (RIE) có thể là câu trả lời

Có, bạn sẽ phải xây dựng thực thể kho dữ liệu bổ sung và điền vào nó một cách thích hợp. Có, có một số ràng buộc mà bạn sẽ phải chơi xung quanh (một giới hạn là 5000 giới hạn về độ dài của thuộc tính danh sách trong kho dữ liệu GAE). Nhưng các tìm kiếm kết quả là nhanh như chớp.

Để biết chi tiết, xem RIE của tôi với Java và OjbectifyRIE với các bài đăng Python .


0

"Thích" thường được sử dụng như là một thay thế cho người nghèo để tìm kiếm văn bản. Để tìm kiếm văn bản, có thể sử dụng Whoosh-AppEngine .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.