datastore query 问题

2010-12-10 06:56:06 +08:00
 timshi
假设我有这样一个 model

class Person{
@Persistent
private List<Category> tags = ArrayList<Category>()
}

I want to let the user query a person based on his/her tag, so I had my query filter like this:

tags.contains(tagValue1)

and if the user want to search for multiple tags, I would just add to the filter so if the user is searching for 3 tags, then the query would be

tags.contains(tagValue1) && tags.contains(tagValue2) && tags.contains(tagValue3)

I think this approach is wrong, because the datastore then needs to have an index that have the tags property three times... and if the user search for more than 3 tags at a time then it will be broken.

What's the proper way to do this? Do you guys have any suggestions?
4922 次点击
所在节点    问与答
6 条回复
MarkFull
2010-12-10 09:06:43 +08:00
这个是3个queries吧
timshi
2010-12-10 11:44:05 +08:00
你是说我必须做3个query然后再intersect the result myself?
MarkFull
2010-12-10 11:55:09 +08:00
intersect是下策,built-in的GQL我不是很熟悉
timshi
2010-12-10 12:43:49 +08:00
那你会怎么做? 我本来以为这个个index应该是这样的

person1, tagValue1
person1, tagValue2
person1, tagValue3

i.e an additional for each value in the multi-value property, and GAE should do a merge join to get me the result.

But my index file looks like this

<datastore-index kind="Person" ancestor="false" source="auto">
<property name="tags" direction="asc"/>
<property name="tags" direction="asc"/>
<property name="tags" direction="asc"/>
<property name="tags" direction="asc"/>
.....
MarkFull
2010-12-10 12:58:25 +08:00
no, each property should specify once for the same kind (Person).
There should be only one line of <property name="tags" direction="asc"/>

This is the GQL format you can reference:
SELECT [* | __key__] FROM <kind>
[WHERE <condition> [AND <condition> ...]]
[ORDER BY <property> [ASC | DESC] [, <property> [ASC | DESC] ...]]
[LIMIT [<offset>,]<count>]
[OFFSET <offset>]

<condition> := <property> {< | <= | > | >= | = | != } <value>
<condition> := <property> IN <list>
<condition> := ANCESTOR IS <entity or key>
MarkFull
2010-12-10 13:01:30 +08:00
Instead of using GQL, maybe you can use this:

filter(property_operator, value)
Adds a property condition filter to the query. Only entities with properties that meet all of the conditions will be returned by the query.
Arguments:
property_operator
A string containing the property name, and an optional comparison operator. The name and the operator must be separated by a space, as in: age > The following comparison operators are supported: < <= = >= > != IN If the operator is omitted from the string (the argument is just the property name), the filter uses the = operator.
value
The value to use in the comparison on the right-hand side of the expression. Its type should be the value data type for the property being compared. See Types and Property Classes.
query.filter('height >', 42).filter('city = ', 'Seattle')

query.filter('user = ', users.get_current_user())

from http://code.google.com/appengine/docs/python/datastore/queryclass.html#Query_filter

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/5673

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX