sys*_*out 5 python indexing google-app-engine explode google-cloud-datastore
我正在开发一个简单的博客/书签平台,我想添加一个标签,探险家/向下钻取功能点菜美味,以允许用户过滤帖子指定特定标签的列表.
像这样的东西:

使用此简化模型在数据存储区中表示帖子:
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)
Run Code Online (Sandbox Code Playgroud)
Post的标签存储在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)
Run Code Online (Sandbox Code Playgroud)
虽然我没有太多强调,但效果很好.
当我尝试向方法添加"排序"顺序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)
Run Code Online (Sandbox Code Playgroud)
排序顺序为每个标签添加一个索引以进行过滤,从而导致可怕的爆炸索引问题.
使事情变得更复杂的最后一件事是该get_posts方法应该提供一些分页机制.
你知道任何策略/想法/解决方法/黑客来解决这个问题吗?
涉及键的查询使用索引,就像涉及属性的查询一样。在与属性相同的情况下,对键的查询需要自定义索引,但有几个例外:不等式过滤器或键的升序排序不需要自定义索引,但 Entity.KEY_RESERVED_PROPERTY_ key _ 的降序排序需要自定义索引。
因此,使用可排序的日期字符串作为实体的主键:
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)
Run Code Online (Sandbox Code Playgroud)
...
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)
Run Code Online (Sandbox Code Playgroud)
现在,您甚至不必在查询中包含排序顺序,尽管按键显式排序不会有什么坏处。
要记住的事情:
| 归档时间: |
|
| 查看次数: |
771 次 |
| 最近记录: |