我正在学习GAE工作。我已经阅读了很多论文,所有来自谷歌的NDB文档和asome问题都在这里。我已经习惯了SQL,但是将我过去20年的思维方式转变为NoSQL对我来说有点困难,所有这些不同的解决方案都让我疯狂。
我有下一个简单的结构: 书本比可以有章节 可以有投票的章节 例如,Book“Sentinel”可以有3章,每章将分别有0,8和12票。
在传统的SQL中,我只需要将外键从VOTES到CHAPTERS和BOOKS,从CHAPTERS到BOOKS。
我为我的模特做了这个:
class Book(ndb.Model):
title = ndb.StringProperty(required=True)
author = ndb.StringProperty(required=True)
created = ndb.DateTimeProperty(auto_now_add=True)
# Define a default ancestor for all the books
@staticmethod
def bookKey(group='books'):
return ndb.Key(Book, group)
# Search all
@classmethod
def getAll(cls):
q = Book.query(ancestor=cls.bookKey())
q = q.order(Book.title)
books = q.fetch(100)
return books
@classmethod
def byId(cls, id):
book = Book.get_by_id(long(id), cls.bookKey())
# Get all the Chapters for a book
def getChapters(self):
chapters = Chapter.query(ancestor=self).order(Chapter.number).fetch(100)
return chapters
class Chapter(ndb.Model):
""" All chapters that a book have """
title = ndb.StringProperty(required=True)
number = ndb.IntegerProperty(default=1)
created = ndb.DateTimeProperty(auto_now_add=True)
book = ndb.KeyProperty(kind=Book)
# Search by Book (parent)
@classmethod
def byBook(cls, book, limit=100):
chapter = book.getChapters()
return chapter
# Search by id
@classmethod
def byId(cls, id, book):
return Chapter.get_by_id(long(id), parent=book)
class Vote(ndb.Model):
""" All votes that a book-chapter have """
value = ndb.IntegerProperty(default=1)
book = ndb.KeyProperty(kind=Book)
chapter = ndb.KeyProperty(kind=Chapter)
好吧,我的怀疑是:
最后,我将展示包含所有书籍的单个表格。在表格中,我希望得到每本书的所有选票总和。例如:
姓名|投票 Sentinel | 30票 巫婆| 4票
我如何获得这些信息,特别是计票数。
然后,点击书名,我想展示他的所有章节(当我必须在章节模型上使用byBook函数时,我会说这是对的吗?)。
我需要获取此类数据的GQL是什么?
提前致谢。
答案 0 :(得分:2)
良好的开端。 GAE的数据存储有点令人困惑。因为它是无模式的,所以我发现处理实体更像是处理内存中的对象/数据结构而不是处理数据库表。
以下是我要做的一些不同的事情:
您似乎在一个祖先下创建了所有书籍。可怕的主意。在性能方面让你失望。除非您需要对当前代码中没有的一组书籍进行某些交易操作,否则这是不对的。
从Book.getChapters()函数看,你想让一本书成为一堆章节的祖先。这可能是祖先的一个很好的用途。我没有看到您创建章节的代码,但请确保将相应的书指定为祖先。
我只是在一本书或一章中包含投票作为属性。没有必要将它作为一个单独的类型,您需要发出额外的查询。
如果每本书的章节数量有限,我会考虑在章节中使用StructuredProperty。 StructuredProperties本质上是父实体(Book)中的结构化数据。您将受到Book实体的最大大小(1MB)的限制,但如果它适合,它将为您节省额外查询的成本,因为如果没有相应的书籍,您将不会查询章节。< / p>