Question

I have some properties, let's say

color = blue
age = 22
name = Tom

Of a number of entities in the datastore, how can I get one that matches most of the properties? Of course I could do:

query.filter('color =', 'blue')
query.filter('age =', '22')
query.filter('name =', 'Tom')

But if no such entity with the exact properties exists, it does not give a result. How can I get entities where at least two filters match, or if that still does not work, one filter..? It doesn't need to calculate similarity of the values or something, just give me entities where most filters as possible match.

Was it helpful?

Solution

You are basically asking for an OR operator, which is not possible to do with a single query. I think you have two options:

1) Add an OR operator by subclassing MultiQuery. This will still execute several queries under the hood and ordering and cursors won't work.

2) Pre-compute all possible combinations of your three properties, put them into a StringListProperty, and then use the IN operator. For example, your model would look as follows:

m.col_age_name = ['c:blue, a:22', 'c:blue, n:Tom', \
                  'a:22, n:Tom', 'a:22, c:blue, n:Tom']

Then you run the filter:

q.filter('col_age_name IN', ['c:blue, a:22', 'c:blue, n:Tom', 'a:22, n:Tom'])

This solution has problems: (a) it performs several queries under the hood, (b) you need to run it three times (once for 1, 2, and 3 properties), (c) it won't support order or cursors, and (d) it makes managing the data a mess. The only benefit is that it reduces the maximum number of filter calls you need to make from 7 to 3.

It is clearly more hassle than it's worth. I would just run the simple query seven times, which has disadvantages (a) and (c) but not (d).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top