Executing DISTINCT query with objectify for app engine

旧巷老猫 提交于 2019-12-12 16:45:43

问题


Given the following two tables, how do I write/execute the following query in objectify:

SELECT DISTINCT(authorId) FROM Book ORDER BY date DESCENDING LIMIT 30.

@Entity
Book{
  @Id
  private Long bookId;//auto generated
  private Key<Author> authorKey;
  private String title;
  private Date date;
  …
}

@Entity
Author{
  @Id
  private Long authorId;//auto generated
  private String name;
  …
}

Note that all I am looking for in my result is a list of authorIds, as in

public List<Long> getActiveAuthors(){
  ...objectify query goes here
}

The english version may be a bit confusing, but here goes: I am trying to get the 30 authors who have most recently published books. The assumption is that each author has written a multitude of books. And since each book has a publication date, I want to know the 30 authors who have been active "recently". If you find this natural language explanation distracting, simply ignore it: the SQL says it well.


回答1:


@stickfigure is usually the expert on objectify, but his response is a bit puzzling. I was under the impression you could use

List<Book> booksProjection = ofy().load().type(Book.class).project(“authorKey”).
distinct(true).order("-publicationDate").limit(30).list();

Then once you get the booksProjection the rest is as simple as extracting the authorKeys and then query for the authors; so that your final answer would be

public static Collection<Author> getActiveAuthors() {

    List<Book> result = ofy().load().type(Book.class).project("AuthorKey").distinct(true).order("-publicationDate").limit(30).list();
    List<Key<Author>> AuthorKeys = new ArrayList<>(result.size());
    for(Book n: result){
      AuthorKeys.add(n.getAuthorKey());
    }
    return ofy().load().keys(AuthorKeys).values();
  }



回答2:


You can't really do this as an ad-hoc query with the GAE datastore. The generally recommended way to address this specific problem is to save an indexed "lastPlublishDate" property on the Author entity and keep it updated. Then you can answer the question with a simple order query.

However, if you're looking for a broader general solution for ad hoc analytical queries, the best answer is probably to replicate a copy of the data into an external index (say, Cloud SQL) using the task queue. Then you can ask any question you want, no matter how compute intensive, without risk that your primary datastore will get swamped.



来源:https://stackoverflow.com/questions/32938795/executing-distinct-query-with-objectify-for-app-engine

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!