Mongodb/Mongoose查询

h5qlskok  于 12个月前  发布在  Go
关注(0)|答案(1)|浏览(102)

一个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,但后来写了一篇文章1小时前,得分50,我会出现-但我不应该,因为我的最新的文章(这是在最后一天内写的)没有得分80-90之间。
另外,如果有人在最后一天写了两篇文章,并且都得到了85分,这将得到重复的结果。请注意,distinct不能与populate在同一个字段上一起工作。
这个查询范围太广了。我需要得到所有最近一篇文章(必须是在最后一天写的)在80-90之间的人。

r6l8ljro

r6l8ljro1#

我能想到的唯一方法是通过查询User集合来形成所有最后Essay s _id s的数组:

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,以使用ObjectId::getTimestamp方法将它们的生成日期与yesterday日期进行比较。

相关问题