【问题标题】:mongoose mapreduce()猫鼬 mapreduce()
【发布时间】:2012-02-09 05:24:14
【问题描述】:

我正在跟踪玩家的得分以记录成长。我的架构如下:

Schema = new schema({
    pid: { type: Number }
  , name: { type: String }
  , alliance: {
      aid: { type: Number }
    , name: { type: String }
    }
  , city_cnt: { type: Number }
  , score: { type: Number }
  , rank: { type: Number }
  , createdTimeAt: { type: Date, default: Date.now }
  , createdDayAt: { type: Number, default: function() { return Math.floor(Date.now() / (24 * 60 * 60)) } }
})

现在我想为每位玩家每天提取一条记录(即当天最后记录的得分)。所以我有这张地图减少:

growthMap = function(){
  emit('createdTimeAt', this.createdTimeAt.toString())
}

growthReduce = function(prev, doc) { 
  if (doc.createdTimeAt > prev.createdTimeAt) {
    prev.createdTimeAt = doc.createdTimeAt
    prev.score = doc.score

    prev.pid = doc.pid
    prev.name = doc.name
  }
}

mongoose.connect('mongodb://localhost/my_database')
mongoose.model('Players', Schema)

mongoose.connection.db.executeDbCommand({
  mapreduce: 'players'
, map: growthMap.toString()
, reduce: growthReduce.toString()
, out: 'playerGrowth'
}, function(err, ret){ 
  if (err) console.log(err)
  else {
    console.log(ret.documents)
    mongoose.connection.db.collection('playerGrowths', function(err, collection){
      collection.find({}).toArray(function(err, docs){
        console.dir(docs)
      })

    })
  }
})

地图减少似乎工作正常。第一个输出 console.log(ret.documents) 产生这个结果:

[ { result: 'playerGrowth',
    timeMillis: 11268,
    counts: { input: 14635, emit: 14635, reduce: 15, output: 1 },
    ok: 1 } ]

但是,每当我尝试在第二个输出 console.log(docs) 中查询新集合时,我都会得到一个没有结果的空数组。我确定我做错了什么,但是在 mapreduce 方面缺少 mongoose 文档。

编辑

根据下面 Jed 的回答,我将 mongoose.connection.db.collection('playerGrowths' 更改为 mongoose.connection.db.collection('playerGrowth' 并且我' m 至少从 find({}).toArray() 中得到一个结果。但是,它仍然不是我所期望或需要的......

我的新结果

[ { result: 'playerGrowth',
    timeMillis: 5743,
    counts: { input: 14635, emit: 14635, reduce: 15, output: 1 },
    ok: 1 } ]
null
[ { _id: 'createdTimeAt', value: null } ]

【问题讨论】:

  • 我认为,如果我错了 Jed,请纠正我,但是你在模型/集合名称中看到的多个是猫鼬引起的,当我们达到这个级别时调用 mapReduce,我们与 mongodb 交谈,后者不使用名称。

标签: node.js mongodb mongoose


【解决方案1】:

尝试改变:

mongoose.connection.db.collection('playerGrowths'...

收件人:

mongoose.connection.db.collection('playerGrowth'...

【讨论】:

  • 嗯,至少我不再得到一个空数组了。现在它给了我 [ { _id: 'createdTimeAt', value: null } ]
  • 尝试将模型名称更改为 player,然后将 mapreduce 设置为:players
  • 实际上最好让模型成为大写 P 的玩家。
【解决方案2】:

mapreduce 的结果只是一些诊断。现在您需要查询 playerGrowth 集合以获取实际产生的结果。

【讨论】:

    【解决方案3】:

    emit() 函数应该返回一个键值对。由于您的“关键”是“createdTimeAt”,因此它是聚合结果的依据。你应该这样做:

    emit(this.createdTimeAt.toString(), <your value>)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-16
      • 2017-10-08
      • 2020-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-25
      相关资源
      最近更新 更多