Итак, я в основном разрабатываю схему временного ряда для своего кода;Обновление вложенных массивов с помощью mongoose
var GameStatisticsSchema = new mongoose.Schema({
game: { type: mongoose.Schema.ObjectId, ref: 'Game', required: true },
months: [
{ // monthly viewers
epoch: { type: Number, required: true }, // entry time stamp
weeks: [
{ // weekly viewers
epoch: { type: Number, required: true }, // entry time stamp
days: [
{ // daily viewers
epoch: { type: Number, required: true }, // entry time stamp
hours: [
{ // hourly viewers
epoch: { type: Number, required: true }, // entry time stamp
statistics: [
{ // per minute statistics.
viewers: { type: Number },
channels: { type: Number },
}]
}]
}]
}]
}]
});
В основном данные хранятся как - поэтому я могу запрашивать данные за день, в минуту, в неделю, как мне нравится;
{
"_id" : ObjectId("56a78e337a9a34f8a368f719"),
"game" : ObjectId("56a6f0b5bbfbbad0550450ee"),
"months" : {
"1" : {
"weeks" : {
"5" : {
"days" : {
"26" : {
"hours" : {
"17" : {
"statistics" : {
"18" : {
"channels" : NumberInt(46),
"viewers" : NumberInt(308)
}
},
"epoch" : NumberInt(1453820400)
}
},
"epoch" : NumberInt(1453759200)
}
},
"epoch" : NumberInt(1453672800)
}
},
"epoch" : NumberInt(1451599200)
}
},
"__v" : NumberInt(0)
}
В основном я использую findOneAndUpdate(), чтобы вставить мой поминутной данные датчика;
function updateStatistics(game, data) {
return new Promise(function (resolve, reject) {
// get current time
var now = moment();
var minute = now.minute();
var hour = now.hour();
var day = now.date();
var week = now.week();
var month = now.month() + 1; // moment months are 0 indexed
// we'll store per hour, day, week and month subdocuments. so set the epochs for those.
var update = {};
update["months." + month + ".epoch"] = moment().startOf('month').unix();
update["months." + month + ".weeks." + week + ".epoch"] = moment().startOf('isoWeek').unix();
update["months." + month + ".weeks." + week + ".days." + day + ".epoch"] = moment().startOf('day').unix();
update["months." + month + ".weeks." + week + ".days." + day + ".hours." + hour + ".epoch"] = moment().startOf('hour').unix();
// set the viewers & channels.
update["months." + month + ".weeks." + week + ".days." + day + ".hours." + hour + ".statistics." + minute + ".viewers"] = data.viewers;
update["months." + month + ".weeks." + week + ".days." + day + ".hours." + hour + ".statistics." + minute + ".channels"] = data.channels;
GameStatistics.findOneAndUpdate(
{ "game": game._id },
{ $set: update },
{
new: true, // return the updated document
upsert: true, // create the document if does not exist
runValidators: true,
setDefaultsOnInsert: true
},
function(err, document) {
if(err)
reject(err);
resolve();
}
);
});
}
Дело в том, что после включения;
runValidators: true,
setDefaultsOnInsert: true
Мой валидатор выпустит исключение;
Cannot update 'months.1.epoch' and 'months' at the same time
Так, если отключить runValidators, я могу хранить данные как это так, но документ становится схема меньше - и получается identicial к этому;
var GameStatisticsSchema = new mongoose.Schema({
game: { type: mongoose.Schema.ObjectId, ref: 'Game', required: true },
months: [ { type: mongoose.Schema.Mixed }]
});
Итак, какие-нибудь обходные пути, которые вы можете предложить?
Причина, по которой я использую upset enabled findOneAndUpdate, заключается в том, что без этого я не знаю, как создавать вложенные значения массива и сохранять() документ.
Имейте в виду, что - за 26.01.2015 15:35:13, код необходимо вставить в это;
months[1].weeks[5].days[26].hours[15].minutes[35].statistics.{
viewers = 25;
channels = 50
}
Потому что я хотел бы получить за неделю, за день, за час, за месяц-данные. С вашим предложением, учитывая, что частота данных метки времени составляет минуту, вы сможете запросить только данные за минуту. С моей текущей схемой я могу запросить, например, данные за неделю, усредняя значения для диапазона дат, который мне нужен. – HuseyinUslu
Вы можете сделать то же самое с запросом даты, усредняя все результаты: find ({date: {$ gt: new Date (2016, 0, 1), $ lt: new Date (2016, 1, 1)}}) for вся статистика в январе –
Хорошо, пожалуйста, покажите мне, как получить данные за последние 4 недели с этим? Посредством усреднения я имею в виду, что я могу подключить обновление схемы и вычислить средние значения за период в документе, а затем это будет простая операция доступа. – HuseyinUslu