Mongodb聚合与客户端处理

我有一个几乎具有以下模式的blogs集合:

 { title: { name: "My First Blog Post", postDate: "01-28-11" }, content: "Here is my super long post ...", comments: [ { text: "This post sucks!" , name: "seanhess" , created: 01-28-14} , { text: "I know! I wish it were longer" , name: "bob" , postDate: 01-28-11} ] } 

我主要想运行三个查询:

  1. 给我所有的comments 只有 bob
  2. find所有写在同一天发表的comments.postDate = title.postDate ,这是comments.postDate = title.postDate
  3. 查找bob在写bob文章的同一天所做的所有comments

我的问题如下:

  • 这三个将是真正频繁的查询,所以使用聚合框架是一个好主意?
  • 对于第三个查询,我可以简单地做一个查询,如db.blogs.find({"comments.name":"bob"}, {comments.name:1, comments.postDate:1, title.postDate:1})然后做一个客户端的后期处理循环返回的结果。 这是个好主意吗? 我想指出,这可能会返回几千个文件。
  • 如果你能提出一些方法来做第三个查询,我会很高兴。

在这里最好的做法是将你的多个问题“分解”为几个问题,如果不仅仅是为了这个问题的答案, 可能会理解另一个问题。

我也不太热衷于回答没有任何事例可以certificate你所做的事情。 但是有了这样的说法和“自in自在”,从devise的angular度来看这些问题是合理的,所以我会回答。

要点1:评论“bob”

Standard $展开并过滤结果。 首先使用$ match,这样就不会处理不需要的文档。

 db.collection.aggregate([ // Match to "narrow down" the documents. { "$match": { "comments.name": "bob" }}, // Unwind the array { "$unwind": "$comments" }, // Match and "filter" just the "bob" comments { "$match": { "comments.name": "bob" }}, // Possibly wind back the array { "$group": { "_id": "$_id", "title": { "$first": "$title" }, "content": { "$first": "$content" }, "comments": { "$push": "$comments" } }} ]) 

第二点:同一天的所有评论

 db.collection.aggregate([ // Try and match posts within a date or range // { "$match": { "title.postDate": Date( /* something */ ) }}, // Unwind the array { "$unwind": "$comments" }, // Aha! Project out the same day. Not the time-stamp. { "$project": { "title": 1, "content": 1, "comments": 1, "same": { "$eq": [ { "year" : { "$year": "$title.postDate" }, "month" : { "$month": "$title.postDate" }, "day": { "$dayOfMonth": "$title.postDate" } }, { "year" : { "$year": "$comments.postDate" }, "month" : { "$month": $comments.postDate" }, "day": { "$dayOfMonth": "$comments.postDate" } } ]} }}, // Match the things on the "same { "$match": { "same": true } }, // Possibly wind back the array { "$group": { "_id": "$_id", "title": { "$first": "$title" }, "content": { "$first": "$content" }, "comments": { "$push": "$comments" } }} ]) 

第3点:同一天的“bob”

 db.collection.aggregate([ // Try and match posts within a date or range // { "$match": { "title.postDate": Date( /* something */ ) }}, // Unwind the array { "$unwind": "$comments" }, // Aha! Project out the same day. Not the time-stamp. { "$project": { "title": 1, "content": 1, "comments": 1, "same": { "$eq": [ { "year" : { "$year": "$title.postDate" }, "month" : { "$month": "$title.postDate" }, "day": { "$dayOfMonth": "$title.postDate" } }, { "year" : { "$year": "$comments.postDate" }, "month" : { "$month": $comments.postDate" }, "day": { "$dayOfMonth": "$comments.postDate" } } ]} }}, // Match the things on the "same { "$match": { "same": true, "comments.name": "bob" } }, // Possibly wind back the array { "$group": { "_id": "$_id", "title": { "$first": "$title" }, "content": { "$first": "$content" }, "comments": { "$push": "$comments" } }} ]) 

结果

说实话,特别是如果你正在使用一些索引来提供这些操作的初始$匹配阶段,那么应该非常清楚的是,这将围绕尝试在代码中进行迭代来“运行”。

这样至less可以减less返回的logging“通过networking ,所以networkingstream量较less。 一旦收到查询结果,当然就没有(或没有发布过程

作为一般惯例,数据库服务器硬件的性能往往比“应用服务器”硬件高一个数量级 。 所以一般情况下,在服务器上执行的任何东西都会运行得更快。

  • 聚合是正确的事情 :“是”。 并且很长的路要走。 你甚至会很快得到一个游标

  • 你怎么能做你想要的查询 :显示很简单。 而在现实世界的代码中,我们从来没有“硬编码”,我们dynamic地构build它。 所以添加条件和属性应该像所有正常的数据操作代码一样简单。

所以我通常不会回答这样的问题。 但是说声谢谢! 请 ?