加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

Tastypie-nonrel,django,mongodb:太多的筑巢

发布时间:2020-12-20 13:30:13 所属栏目:Python 来源:网络整理
导读:我正在使用 django,backbone.js,tastypie和mongodb开发一个Web应用程序.为了使tastypie和django适应mongodb,我正在使用django-mongodb-engine和tastypie-nonrel.该应用程序有一个模型Project,它有一个Tasks列表.所以它看起来像这样: class Project(models.M
我正在使用 django,backbone.js,tastypie和mongodb开发一个Web应用程序.为了使tastypie和django适应mongodb,我正在使用django-mongodb-engine和tastypie-nonrel.该应用程序有一个模型Project,它有一个Tasks列表.所以它看起来像这样:

class Project(models.Model):
       user = models.ForeignKey(User)
       tasks = ListField(EmbeddedModelField('Task'),null=True,blank=True)

   class Task(models.Model):
       title = models.CharField(max_length=200)

感谢tastypie-nonrel,在/ api / v1 / project /:id:/ tasks /中使用GET请求以简单的方式获取项目任务列表

现在我想用一个注释列表扩展这个Task模型:

class Task(models.Model):
       title = models.CharField(max_length=200)
       comments = ListField(EmbeddedModelField('Comment'),blank=True)

   class Comment(models.Model):
       text = models.CharField(max_length=1000)
       owner = models.ForeignKey(User)

这个实现的问题是tastypie-nonrel不支持另一个嵌套,因此不可能简单地将注释POST到/ api / v1 / project /:id:/ task /:id:/ comments /

另一种方法是将任务的PUT请求发送到/ api / v1 / project /:id:/ task /,但如果两个用户决定同时向同一个任务添加注释,则会产生问题,如最后一个PUT将覆盖前一个PUT.

最后一个选项(除了更改tastypie-nonrel之外)是不在任务中嵌入Comment并只保留ForeignKey,因此请求将转到/ api / v1 / Comment /.我的问题是,如果这打破了使用MongoDB的好处(因为它需要交叉查询)?有没有更好的方法呢?

我对堆栈的任何技术都没有什么经验,所以我可能不会很好地关注这个问题.欢迎任何建议.

解决方法

好像你在筑巢太多了.也就是说,您可以为tastypie创建自定义方法/ URL映射,然后运行您自己的逻辑,而不是依赖于“自动魔术”tastypie.如果您担心评论覆盖问题,则无论如何都需要进行交易.然后,您的代码应足够健壮,以处理失败事务的行为,例如重试.如果您经常锁定具有许多编写器的大型对象,这将极大地限制您的写入,但是,这也指向了设计问题.

一种可以缓解此问题的方法是写入中间源(如任务队列或redis),然后根据需要转储到注释中.这取决于您的解决方案的可靠性/耐用性.任务队列至少会处理失败事务的重试;使用redis,你可以用pub / sub做点什么.

您应该考虑一下有关MongoDB的设计IMO的一些事项.

>避免创建过大的整体对象.虽然这是Mongo的好处,但这取决于您的使用情况.例如,如果您始终将项目作为顶级对象返回,那么随着任务和注释的增长,仅网络流量就会降低性能.

想象一下这个项目具体的非常人为的例子
数据是10k,每个任务单独是5k,每个评论单独是2k,如果你有一个项目有5个任务,每个任务10个评论,你说的是10k 5 * 5k 10 * 2k.对于一个包含大量注释的非常活跃的项目,这将是通过网络发送的大量内容.您可以执行切片/投影查询以协调此问题,但具有一些限制和含义.
>上述的必然结果,将对象结构化为用例.如果您不需要将各种东西重新组合在一起,它们可以位于不同的集合中.仅仅因为你“思考”你需要将它们重新组合在一起,并不意味着实现明智,它们需要在相同的提取中检索(尽管这通常是理想的).

即使您确实需要一个用例/屏幕中的所有内容,在某些设计中可能采用的另一种解决方案是使用AJAX并行加载内容,或者甚至在页面加载后通过JavaScript延迟.例如,您可以在顶部加载任务信息,然后进行异步调用以单独加载注释,类似于Disqus或Livefyre作为其他站点中的集成的工作方式.这有助于解决您的嵌套问题,因为您已经摆脱了任务/项目级别,只需在每个注释/记录上存储一些ID,以便能够在集合之间进行查询.
>请记住,您可能不想一次检索所有评论,如果您有很多评论,您可能会遇到一个文档大小的限制.在最近的Mongo版本中,这些天的大小更大,但是无论如何通常没有意义的是拥有大量数据的单个记录,回到上面的第一项.

我的建议是:

>如果您担心丢失评论,请使用交易.>如果您担心由于#1而导致竞争写入和丢失事物,请添加任务队列/ redis / something.如果没有,请忽略它.如果你失去评论,这是世界末日吗?>考虑将特别评论重组到一个单独的集合中,以减轻您的tastypie问题.如果需要,可以加载延迟或并行的内容.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读