Mongodb/Mongoose 查询

问题描述 投票:0回答:2

一个

User
有一堆
Essays
,存储为 ObjectId 数组。在 CoffeeScript 中,架构是:

User = new Schema
  essays: [Schema.Types.ObjectId]
  name: String

Essay = new Schema
  grade: Number
  text: String
  author: Schema.Types.ObjectId

如何在一个查询中获取最新论文是在最后一天撰写且最新论文评分在 80 到 90 之间的所有不同用户?

我有这个(在 CoffeeScript 中):

req.mongoose.Essay
  .find(
    _id:
      $gt:
        # trick which creates an ObjectId with yesterday's timestamp
        mongoose.Types.ObjectId.createFromHexString(
          (~~(yesterday.getTime() / 1000)).toString(16) +
          "0000000000000000"
        )
  )
  .where("grade").gt(80).lt(90)
  .popluate(path: "User")
  .exec (err, docs) ->
    console.log ({name: essay.author.name} for essay in docs)

这很接近,但不完全是。

这将使任何在最后一天写过论文且论文得分在 80-90 之间的人得到结果。例如,如果我两小时前写了一篇文章并获得了 85 分,但一小时前写了一篇文章并获得了 50 分,我会出现 - 但我不应该出现,因为我的最新文章(这是写的)最后一天内)得分未在 80-90 之间。

此外,如果有人在最后一天写了两篇论文并且两篇论文都得到了 85 分,那么这将会重复。请注意,

distinct
不能与
populate
在同一字段上一起使用。

这个查询太宽泛了。我需要找到所有最新论文(必须在最后一天写的)在 80-90 之间的人。

node.js mongodb coffeescript mongoose
2个回答
2
投票

我能想到的唯一方法是通过查询

Essay
集合来形成所有最后
_id
User
的数组:

req.mongoose.User
  .find(essays: $not: $size: 0) # Just to be sure
  .select(essays: $slice: -1) # We only interested in last Essay
  .lean() # It's faster
  .exec (err, users) ->
    ids = users.map ({essays}) ->
      # essays array contains exactly one [last] element
      essays[0]
    .filter (_id) ->
      # We only interested in yesterday Essays
      _id.getTimestamp() >= yesterday
    req.mongoose.Essay
      .find(_id: $in ids)
      .where('grade').gt(80).lt(90)
      .popluate('User')
      .exec (err, docs) ->
        console.log ({name: essay.author.name} for essay in docs)

请注意,它还允许我正确过滤获取的

ids
,以使用
yesterday 方法
将它们的生成日期与 
ObjectId::getTimestamp
日期进行比较。


0
投票

花点时间想想你需要花多少时间来完成任务。老实说,光是想到它就会让你感到畏缩,尤其是当你必须在紧迫的时间内涵盖不同的主题时。

© www.soinside.com 2019 - 2024. All rights reserved.