首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关系索引实体与投影查询

关系索引实体与投影查询
EN

Stack Overflow用户
提问于 2017-03-01 05:03:23
回答 1查看 132关注 0票数 1

我正在为经典的“用户帖子”和“标签”问题设计谷歌数据存储模式。

这个页面建议建立关系索引实体模型。基本上,它将可搜索的标记或关键字作为子实体中的列表属性进行过滤,在父实体中放置必要的属性。据我理解,这种方法是减少查询时的序列化开销。

代码语言:javascript
复制
class Post(db.Model):
  title = db.StringProperty()
  post_date = db.DateTimeProperty()

class Tags(db.Model):
  tags = db.StringListProperty()

mytags = Tags(parent=post, tags=many_tags)
  1. 如果投影查询可以获得属性的子集,那么关系索引实体是否仍然需要减少列表属性的序列化开销?

注意:投影查询有限制;关系索引实体没有。

  1. 关系索引实体是否使查询更加困难?说我想要过滤标签‘汽车’的帖子在过去7天内创建。标签和post_date有不同的种类,有什么简单的方法吗?
  2. 对于爆炸性索引,关系索引实体是否降低了爆炸索引的机会,因为它将列表属性放在不同的类型中?

谢谢你提前回答。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-01 06:27:38

  1. Relation解决方案减少了的序列化开销--任何类型的对Post实体的访问,包括key.get()、`entity.put()或获取非投影查询之类的操作,而投影查询只用于获取相应的查询结果。
  2. 是的,查询有点困难。对于您的示例,您将需要单独的查询,每个实体类型都需要一个查询。

该示例假设使用的是ndb,而不是db

代码语言:javascript
复制
from google.appengine.ext import ndb

class Post(ndb.Model):
  title = ndb.StringProperty()
  post_date = ndb.DateTimeProperty()

class Tags(ndb.Model):
  tags = ndb.StringProperty(repeated=True)

我只使用密钥查询,因为它们更便宜,速度更快:

代码语言:javascript
复制
from datetime import datetime, timedelta

car_post_keys = []
post_keys = Post.query(Post.post_date>(datetime.utcnow() - timedelta(days=7)),
                       keys_only=True).fetch()
if post_keys is not None:
    for post_key in post_keys:
        if Tags.query(Tags.tags=='car', ancestor=post_key, keys_only=True).fetch() is not None:
            car_post_keys.append(post_key)

car_posts = ndb.get_multi(car_post_keys) if car_post_keys else []
  1. 一般来说,答案是肯定的,这正是你提到的原因。在您的特定示例中,只有一个具有多个值的属性-- tags --以及少量其他Post属性,所有这些属性都具有单个值,因此爆炸索引影响的差异可能是可以忽略的。

将一个实体拆分成几个较小的实体也是一种常见的技术,因为还有其他原因,例如,请参见为其他不同类型的实体重新使用实体的ID -明智的想法?

这里有一个应用这个想法的例子:

代码语言:javascript
复制
car_post_key_ids = []

post_keys = Post.query(Post.post_date>(datetime.utcnow() - timedelta(days=7)),
                       keys_only=True).fetch()
if post_keys is not None:
    post_key_ids = [key.id() for key in post_keys]

    car_tag_keys = Tags.query(Tags.tags=='car', keys_only=True).fetch()
    car_tag_key_ids = [key.id() for key in car_tag_keys] if car_tag_keys is not None else []

    car_post_key_ids = list(set(post_key_ids) & set(car_tag_key_ids))

car_posts = [Post.get_by_id(id) for id in car_post_key_ids]

示例非常简单,可以使用ndb异步调用、任务/线程、许多结果可能需要游标等对它们进行优化。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42523602

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档