- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试查询一个集合并检索过去 7 天(不包括当天)每一天的平均值。在某些或所有的日子里,可能没有平均值。
这是我目前所拥有的:
var dateTill = moment({hour:0,minute:0}).subtract(1, 'days')._d
var dateSevenDaysAgo = moment({hour:0,minute:0}).subtract(7, 'days')._d;
Rating.aggregate([
{
$match:{
userTo:facebookId,
timestamp:{$gt:dateSevenDaysAgo,$lt:dateTill}
}
},
{
$group:{
_id:{day:{'$dayOfMonth':'$timestamp'}},
average:{$avg:'$rating'}
}
},
{
$sort:{
'_id.day':1
}
}
]
这给了我
[ { _id: { day: 20 }, average: 1 },
{ _id: { day: 22 }, average: 3 },
{ _id: { day: 24 }, average: 5 } ]
我想得到的是这样的:
[1,,3,,5,,]
按顺序表示最近 7 天的平均值,并且有一个空元素,表示当天没有平均值。
我可以尝试创建一个函数来检测差距在哪里,但是当平均值分布在两个不同的月份时,这将不起作用。例如 (July 28,29,30,31,Aug 1,2] - 八月的日子将被排序到我想要的数组的前面。
有更简单的方法吗?
谢谢!
最佳答案
人们经常询问“空结果”,而他们的想法通常来自他们如何使用 SQL 查询来解决问题。
但是,虽然为不包含分组键的项目抛出一组“空结果”是“可能的”,但这是一个困难的过程,很像人们使用的 SQL 方法,它只是将这些值抛入人为地声明,它确实不是一个非常受性能驱动的替代方案。考虑使用一组制造的 key “加入”。效率不高。
更聪明的方法是直接在客户端 API 中准备好这些结果,而不是发送到服务器。然后聚合输出可以与这些结果“合并”以创建一个完整的集合。
无论您想要存储要合并的集合取决于您,它只需要一个基本的“哈希表”和查找。但这是一个使用 nedb 的例子,它允许你保持 MongoDB 查询和更新的一套思路:
var async = require('async'),
mongoose = require('mongoose'),
DataStore = require('nedb'),
Schema = mongoose.Schema,
db = new DataStore();
mongoose.connect('mongodb://localhost/test');
var Test = mongoose.model(
'Test',
new Schema({},{ strict: false }),
"testdata"
);
var testdata = [
{ "createDate": new Date("2015-07-20"), "value": 2 },
{ "createDate": new Date("2015-07-20"), "value": 4 },
{ "createDate": new Date("2015-07-22"), "value": 4 },
{ "createDate": new Date("2015-07-22"), "value": 6 },
{ "createDate": new Date("2015-07-24"), "value": 6 },
{ "createDate": new Date("2015-07-24"), "value": 8 }
];
var startDate = new Date("2015-07-20"),
endDate = new Date("2015-07-27"),
oneDay = 1000 * 60 * 60 * 24;
async.series(
[
function(callback) {
Test.remove({},callback);
},
function(callback) {
async.each(testdata,function(data,callback) {
Test.create(data,callback);
},callback);
},
function(callback) {
async.parallel(
[
function(callback) {
var tempDate = new Date( startDate.valueOf() );
async.whilst(
function() {
return tempDate.valueOf() <= endDate.valueOf();
},
function(callback) {
var day = tempDate.getUTCDate();
db.update(
{ "day": day },
{ "$inc": { "average": 0 } },
{ "upsert": true },
function(err) {
tempDate = new Date(
tempDate.valueOf() + oneDay
);
callback(err);
}
);
},
callback
);
},
function(callback) {
Test.aggregate(
[
{ "$match": {
"createDate": {
"$gte": startDate,
"$lt": new Date( endDate.valueOf() + oneDay )
}
}},
{ "$group": {
"_id": { "$dayOfMonth": "$createDate" },
"average": { "$avg": "$value" }
}}
],
function(err,results) {
if (err) callback(err);
async.each(results,function(result,callback) {
db.update(
{ "day": result._id },
{ "$inc": { "average": result.average } },
{ "upsert": true },
callback
)
},callback);
}
);
}
],
callback
);
}
],
function(err) {
if (err) throw err;
db.find({},{ "_id": 0 }).sort({ "day": 1 }).exec(function(err,result) {
console.log(result);
mongoose.disconnect();
});
}
);
这给出了这个输出:
[ { day: 20, average: 3 },
{ day: 21, average: 0 },
{ day: 22, average: 5 },
{ day: 23, average: 0 },
{ day: 24, average: 7 },
{ day: 25, average: 0 },
{ day: 26, average: 0 },
{ day: 27, average: 0 } ]
简而言之,“数据存储”是使用 nedb
创建的,它的行为基本上与任何 MongoDB 集合相同(具有精简的功能)。然后,您可以为任何结果插入您的“键”范围内的预期值和默认值。
然后运行您的聚合语句,它只会返回查询集合中存在的键,您只需使用聚合值“更新”创建的具有相同键的数据存储。
为了提高效率,我在 parallel 中同时运行空结果“创建”和“聚合”操作, 利用 "upsert"功能和 $inc
值的运算符。这些不会冲突,这意味着创建可以在聚合运行的同时发生,因此没有延迟。
这很容易集成到您的 API 中,因此您可以拥有所有您想要的键,包括那些在输出集合中没有数据聚合的键。
同样的方法适用于在您的 MongoDB 服务器上使用另一个实际集合来处理非常大的结果集。但是,如果它们非常大,那么无论如何您都应该预先聚合结果,并且只使用标准查询进行抽样。
关于node.js - MongoDB 聚合组最近 7 天的平均评分,值为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31661858/
当我搜索“iphone”时,我有以下记录和分数 - 记录1: 字段名称 - 显示名称:“iPhone” 字段名称 - 名称:“iPhone” 11.654595 = (MATCH) sum of:
Types Description: parent type 1)Parent Type: "product" 2)childType : "ratings" 问题描述:我有一个es查询(q
如果您使用 Freebase 搜索按名称获取任何实体的匹配项,您将获得按 relevance score 排序的结果.例如尝试 Taj Mahal . 我正在尝试使用 Freebase 数据转储获得类
我试图根据多个不同的标准给不同的城市打从 1 到 5 的“分数”,最终将分数相加并决定哪个城市最好。 表“international_tobacco_alcohol”包含居民用于酒精和烟草的收入百分比
我有一年中任何一个季度的索引(“index-2015.1”,“index-2015.2”...) 我在每个索引上有大约 3000 万个文档。 文档有一个文本字段('title') 我的文档排序方式是(
我有一个数组,我想根据为数组中的每个元素分配一个分数来排序。 假设可能的分数范围是 0-100。为了获得该分数,我们将使用 2 个比较数据点,一个权重为 75,一个权重为 25。我们称它们为 valu
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 4 年前。 Improve this qu
做一排星星作为评级是微不足道的,但我不确定做随机数的正确 flutter 方法是什么? 换句话说,假设我的评分最多为 5 颗星,我该怎么做,只有一颗或两颗星?我可以有一个 switch 语句,并返回带
我需要创建一个灵活的(最好是动态的)评分引擎,就像信用评分或保费计算系统一样。有创建评分引擎实践经验的人有任何建议、示例或建议模式吗? 我已经知道: Rete Algorithm FICO The o
我的索引中有以下类型的文档,但由于深度嵌套方面,找不到正确排序的方法。 文档示例: { "metadatas": [{ "name": "name", "timeValidity"
我正在寻找 Lucene (Java) 中的相似性模块,它给出基于权重的分数。我知道这很模糊,最好用一个例子来解释。 Document 1 ----------- Firstname: Frances
我对 Lucene 8 比较陌生,想了解如何将旧版 Solr 4 评分迁移到 Lucene。这就是 Solr 4 目前的做法。 /* * From the SolrRelevan
我正在使用 Lucene 来构建标记共现的大型索引(例如 [elephant,animal]、[melon,fruit]、[宝马,汽车],...)。我使用 BooleanQuery 查询索引以获取绝对
Ratingbar 星未正确显示。我不知道我做错了什么。当我使用自定义样式时,只显示一颗星,它的长度等于 5 星。 风格是: @drawable/manual_ratingbar
我编写了一个程序,它读取 imdb 上排名前 250 的电影的名称和评分,并返回评分的平均值。我有以下程序 import java.io.IOException; import org.jsoup.*
我有一个直截了当的问题,我将 ngram 用于部分匹配。实现效果很好,但得分结果并不像我希望的那样有效。我希望我的分数结果看起来像这样: 柯:.1 Kev:.2 凯维:.3 凯文:.4 相反,我得到以
假设我有一个像这样的 MySQL 表: 软件表: id int name text votes int rating int 其中投票是某人为该项目投票的次数,评分是这些投票的平均值。 示例数据: i
我在索引期间使用过滤器 EdgeNGramTokenFilter。 当我寻找一个词时。当 Lucene 找到完整单词或另一个单词的一部分时,它的评分不会产生差异。 例如,如果我正在查找单词 PUB。我
我们正在使用 java 并使用 elasticsearch java api 开发一个应用程序。我们对元数据建立了索引,并希望在索引时或搜索时使用排名/评分。 而且,我不知道是否可以对用户单击结果时选
有人可以解释(或引用引用资料)用更简单的词来比较 SOLR 和 LUCENE 使用的评分机制。 它们有什么区别吗? 我不太擅长 solr/lucene,但我的发现表明它们似乎不同。 P.S:我只是尝试
我是一名优秀的程序员,十分优秀!