【发布时间】:2016-11-20 15:50:31
【问题描述】:
Google 数据存储区一开始看起来不错,但现在变得如此令人沮丧,但也许只是因为我习惯了关系数据库。总的来说,我对数据存储和 nosql 还很陌生,并且已经进行了大量研究,但似乎找不到解决这个问题的方法。
假设我有一个看起来像这样的 User 类
class User{
@Id
Long id;
String firstName, lastName;
List<Key<User>> friends;
}
我有另一个类将模拟用户这样做的事件
class Event{
Key<User> user;
Date eventTime;
List<Key<User>> receivers;
}
现在我要做的是查询我的朋友所做的事件。 以通常的关系方式,我会说:
select * from Event where user in (select friends from User where id = ?)
以此为出发点我尝试做
// Key<User> userKey = ...
User user = ofy.load.type(User.class).key(userKey).first.now;
List<Key<User>> friends = user.getFriends();
ofy.load.type(Event.class).filter("user in", friends).order("-eventTime")list();
但我听说这 30 个子查询的限制使这不可持续,因为我假设最终某人将拥有超过 30 个朋友,更不用说使用“in”子句将保证您无法获得光标来继续加载事件。我做了很多研究并尝试了很多选择,但除了说“为什么是谷歌,为什么”之外,还没有找到解决这个问题的好方法。
我考虑过的事情:
- 在 event 中添加一个额外的字段,它是用户好友列表的副本,并在 MVP 上使用单个 equals 来查找事件(非常浪费,因为可能有很多很多事件。
- 一次将事件查询分成 30 个朋友的批次,并以某种方式确定一种方法,以确保从基于时间的合成游标中继续检索,然后将它们合并(问题是边缘情况太多,使读取事件变得非常困难。 )
非常感谢您提供的任何意见,因为我 100% 没有想法
TL;DR ~ GAE 对 in-clause 可以处理和 fml 的项目数量有限制。
【问题讨论】:
-
我也看到了那个,但与我的情况无关,因为他/她将所有新闻故事加载到内存缓存中,因为新闻对所有登录用户都是全局的。在我的情况下,事件是由用户创建的,但并非所有用户都看到相同的事件,只有他们自己的朋友列表中的人的事件。感谢您的跟进
-
更不用说我想游标结果,因为可能有很多事件,将所有事件加载到内存缓存中似乎很浪费,这可能随时消失
-
我提到这主要是为了回答中的建议。
-
是的,我也在查看,我在问题中提到了我如何考虑将查询分成 30 个批次,如提供的链接中所述。这对新闻来源可能很好,但问题是有太多的边缘情况,无法使其可靠地为我工作。如果前 90 位朋友多年没有活动怎么办?对他们来说,最近发生的事件通常不是最近发生的事件。我想展示最近的 30 个,但最终以很久以前的事件结束。加载很多我不想要的事件是非常棘手的并且非常浪费:(
标签: java google-app-engine google-cloud-datastore objectify nosql