2

Is there any way to generate queries similar to the like, contains, startswith operators with app engine BigTable database?

So that I could do something similar to:

db(db.some_table.like('someting')).select()

with app engine in web2py.

Kara
  • 6,115
  • 16
  • 50
  • 57
crodjer
  • 13,384
  • 9
  • 38
  • 52
  • Starts with is covered at http://stackoverflow.com/questions/1554600/implementing-starts-with-and-ends-with-queries-with-google-app-engine ; the other 2 aren't possible. – Wooble Dec 22 '10 at 19:34

1 Answers1

7

App engine does not support full text search so short answer is no.

What you can do with web2py is create a computed filed with a list of keywords to search for.

 def tokenize(r): return [x.lower() for x in re.compile('\w+').findall(r.title)]

 db.define_table('data',
    Field('title'),
    Field('keywords','list:string',compute=tokenize,writable=False,readable=False))

On GAE the keywords field is a StringListProperty().

Then instead of searching in title, you search in keywords:

 rows = db(db.data.keywords.contains(my_keyword.lower())).select()

This works on GAE and it is very efficient. The problem now is that you will not be used to combine it in complex queries because of the GAE "exploding" indexes problem. For example is you have N keywords and want to search for two keywords:

 rows = db(db.data.keywords.contains(my_keyword1.lower())&
           db.data.keywords.contains(my_keyword2.lower())).select()

Your index size becomes N^2. So you have to perform more complex queries locally:

 query2=lambda r: my_keyword1.lower() in r.keywords
 rows = db(db.data.keywords.contains(my_keyword1.lower())).select().find(query2)

All of this will also work on GAE and not-on-GAE. It is portable.

mdipierro
  • 4,239
  • 1
  • 19
  • 14