gpt4 book ai didi

python - 排序实体和过滤 ListProperty 而不会导致索引 explode

转载 作者:太空狗 更新时间:2023-10-30 00:52:04 26 4
gpt4 key购买 nike

我正在开发一个简单的博客/书签平台,我正在尝试添加一个tags-explorer/drill-down 功能 là delicious允许用户过滤指定特定标签列表的帖子。

是这样的: enter image description here

帖子在数据存储中用这个简化模型表示:

class Post(db.Model):
title = db.StringProperty(required = True)
link = db.LinkProperty(required = True)
description = db.StringProperty(required = True)
tags = db.ListProperty(str)
created = db.DateTimeProperty(required = True, auto_now_add = True)

帖子的标签存储在 ListProperty 中并且,为了检索带有特定标签列表的帖子列表,Post 模型公开了以下静态方法:

@staticmethod
def get_posts(limit, offset, tags_filter = []):
posts = Post.all()
for tag in tags_filter:
if tag:
posts.filter('tags', tag)
return posts.fetch(limit = limit, offset = offset)

虽然我没有过分强调它,但效果很好。

当我尝试向 get_posts 方法添加“排序”顺序以保持结果按 "-created" 日期排序时,问题出现了:

@staticmethod
def get_posts(limit, offset, tags_filter = []):
posts = Post.all()
for tag in tags_filter:
if tag:
posts.filter('tags', tag)
posts.order("-created")
return posts.fetch(limit = limit, offset = offset)

排序顺序为每个要过滤的标签添加一个索引,导致可怕的索引 explode 问题。
最后一件让这件事变得更复杂的事情是 get_posts 方法应该提供一些分页机制。

您知道解决此问题的任何策略/想法/解决方法/技巧吗?

最佳答案

Queries involving keys use indexes just like queries involving properties. Queries on keys require custom indexes in the same cases as with properties, with a couple of exceptions: inequality filters or an ascending sort order on key do not require a custom index, but a descending sort order on Entity.KEY_RESERVED_PROPERTY_key_ does.

因此使用可排序的日期字符串作为实体的主键:

class Post(db.Model):
title = db.StringProperty(required = True)
link = db.LinkProperty(required = True)
description = db.StringProperty(required = True)
tags = db.ListProperty(str)
created = db.DateTimeProperty(required = True, auto_now_add = True)

@classmethod
def create(*args, **kw):
kw.update(dict(key_name=inverse_millisecond_str() + disambig_chars()))
return Post(*args, **kw)

...

def inverse_microsecond_str(): #gives string of 8 characters from ascii 23 to 'z' which sorts in reverse temporal order
t = datetime.datetime.now()
inv_us = int(1e16 - (time.mktime(t.timetuple()) * 1e6 + t.microsecond)) #no y2k for >100 yrs
base_100_chars = []
while inv_us:
digit, inv_us = inv_us % 100, inv_us / 100
base_100_str = [chr(23 + digit)] + base_100_chars
return "".join(base_100_chars)

现在,您甚至不必在查询中包含排序顺序,尽管显式按键排序不会有什么坏处。

要记住的事情:

  • 除非您在此处为所有帖子使用“创建”,否则这将不起作用。
  • 您必须迁移旧数据
  • 不允许有祖先。
  • 键在每个索引中存储一次,因此保持简短是值得的;这就是我在上面进行 base-100 编码的原因。
  • 这不是 100% 可靠,因为可能会发生键冲突。上面的代码,没有 disambig_chars,名义上给出了事务之间微秒数的可靠性,所以如果你在高峰时间每秒有 10 个帖子,它会失败 1/100,000。但是,对于可能的应用程序引擎时钟滴答问题,我会削减几个数量级,所以我实际上只相信它的 1/1000。如果这还不够好,请添加 disambig_chars;如果您需要 100% 的可靠性,那么您可能不应该使用 App Engine,但我想您可以在 save() 上包含处理键冲突的逻辑。

关于python - 排序实体和过滤 ListProperty 而不会导致索引 explode ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6108051/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com