我正在尝试对GAE的数据存储执行相当复杂的查询,基本上,订阅者可以订阅来自特定城镇或任何城镇(*),特定国家或任何国家(*)的新闻,具体...或任何......(*)
现在,当我想通知订阅者有关ZA的新闻时,我需要找到所有匹配country = ZA的用户以及匹配country = *的用户以及其他字段的用户。
Query<Subscriber> query = ofy().load().type(Subscriber.class);
query = query.filter("searchCategory IN", Arrays.asList(new String[]{"*", category}));
query = query.filter("searchCity IN", Arrays.asList(new String[]{"*", city}));
query = query.filter("searchSuburb IN", Arrays.asList(new String[]{"*", suburb}));
query = query.filter("searchTown IN", Arrays.asList(new String[]{"*", town}));
query = query.filter("searchProvince IN", Arrays.asList(new String[]{"*", province}));
query = query.filter("searchCountry IN", Arrays.asList(new String[]{"*", country}));
query = query.limit(100);
QueryResultIterator<Subscriber> iterator = query.iterator();
while (iterator.hasNext()) {
Subscriber subscriber = iterator.next();
System.out.println(iterator.getCursor().toWebSafeString()); // exception here
}
我正在使用任务队列一次通知大量订阅者,一次100个(根据查询结果在20k到2M之间),游标似乎是分解大量结果的合理方式在可管理的块中...直到我运行应用程序并获得一个Null Pointer Exception试图获取游标 - 结果是在使用IN语句时不支持游标。
因为NOT_EQUAL和IN运算符是用多个实现的 查询,使用它们的查询不支持游标,也不支持游标 使用CompositeFilterOperator.or构造的复合查询 方法
在这种情况下看到我不能使用游标的替代方法是什么?
答案 0 :(得分:2)
根据文档
,我认为你可以使用游标某些NDB查询不支持查询游标,但您可以修复它们。 如果查询使用IN,OR或!=,则查询结果将无法使用 游标除非按键排序。如果申请没有订购 按键结果并调用fetch_page(),它得到一个BadArgumentError。如果 User.query(User.name.IN([ '乔', 'Jane']))。order(User.name).fetch_page(N)出错,将其更改为 User.query(User.name.IN(['Joe','Jane']))。order(User.name,User.key).fetch_page(N)
我建议您更快地切换到NDB并自动缓存
答案 1 :(得分:1)
一种选择是仅使用equals独立运行每个查询。这将允许您只获取一些条目,但是除了光标之外,您还必须记住正在运行的查询。这也不会为您处理重复数据删除 - 如果您发送通知,这可能是一个交易破坏者。
您应该考虑查看prospective search API。这是一个实验性功能,但它完全符合您的要求。
基本思路是,为每个用户指定他们的订阅查询(例如searchCountry=NZ
),然后当您处理新闻文章并将其发送到预期搜索API 时,它可以为您提供与该文章匹配的所有订阅(查询)。