按当前字段和计算值对文档进行排序

时间:2017-06-04 02:15:06

标签: node.js mongodb mongoose mongodb-query aggregation-framework

如何在页面顶部显示最佳评论和最差评论。

我认为用户的“有用”和“非有用”投票应该会对结果产生影响。

我有评论,如果人们点击有用且非有用的按钮,他们的ID会被添加到相应的数组中(有用或不有用)。

你可以通过“总体”得分来判断积极或消极得分是多少。这是1到5.所以1将是最差的,5将是最好的。

我猜如果有人给了一个评分,总分为5分,但只有一个有用,但是有人给了4分,100人点击“有用”,有100人的那个应该显示为最好的积极?

我只想在页面顶部显示2条评论最佳和最差评论,如果与总分相关,则决定因素应该是有用的。所以,如果有2个评论具有相同的总分,其中一个有5个有用,10个不是有用的-5个有用的,而在另一个评论中有人有5个有用,而4个不是有用的,这将是有用的,所以这将显示打破平局。

我正在尝试使用一个mongoose查询而不是聚合,但我认为答案将是聚合。

我猜可能会有一个截止,比如大于3的分数是正面评价,而较低的则是负面评价。

我用猫鼬。 在此先感谢您的帮助。

一些样本数据。

{
    "_id" : ObjectId("5929f89a54aa92274c4e4677"),
    "compId" : ObjectId("58d94c441eb9e52454932db6"),
    "anonId" : ObjectId("5929f88154aa92274c4e4675"),
    "overall" : 3,
    "titleReview" : "53",
    "reviewText" : "53",
    "companyName" : "store1",
    "replies" : [],
    "version" : 2,
    "notUseful" : [ObjectId("58d94c441eb9e52454932db6")],
    "useful" : [],
    "dateCreated" : ISODate("2017-05-27T22:07:22.207Z"),
    "images" : [],
    "__v" : 0
}


{
    "_id" : ObjectId("5929f8dfa1435135fc5e904b"),
    "compId" : ObjectId("58d94c441eb9e52454932db6"),
    "anonId" : ObjectId("5929f8bab0bc8834f41e9cf8"),
    "overall" : 3,
    "titleReview" : "54",
    "reviewText" : "54",
    "companyName" : "store1",
    "replies" : [],
    "version" : 1,
    "notUseful" : [ObjectId("5929f83bf371672714bb8d44"), ObjectId("5929f853f371672714bb8d46")],
    "useful" : [],
    "dateCreated" : ISODate("2017-05-27T22:08:31.516Z"),
    "images" : [],

    "__v" : 0
}


{
    "_id" : ObjectId("5929f956a692e82398aaa2f2"),
    "compId" : ObjectId("58d94c441eb9e52454932db6"),
    "anonId" : ObjectId("5929f93da692e82398aaa2f0"),
    "overall" : 3,
    "titleReview" : "56",
    "reviewText" : "56",
    "companyName" : "store1",
    "replies" : [],
    "version" : 1,
    "notUseful" : [],
    "useful" : [],
    "dateCreated" : ISODate("2017-05-27T22:10:30.608Z"),
    "images" : [],
    "__v" : 0
}

1 个答案:

答案 0 :(得分:0)

如果我正确地阅读了您的问题,那么您似乎希望在对"useful"得分的"nonUseful"分数进行排序时,也要考虑"overall"Model.aggregate([ { "$addFields": { "netUseful": { "$subtract": [ { "$size": "$useful" }, { "$size": "$notUseful" } ] } }}, { "$sort": { "overall": 1, "netUseful": -1 } } ],function(err, result) { }) 投票的计算差异。文档。

这里更好的选择是在您存储的文档中包含计算,但总体而言,我们将涵盖这两个选项。

聚合

如果不更改架构和其他逻辑,则确实需要进行聚合才能进行该计算。最佳表现为:

"useful"

因此,您基本上可以获得两个数组之间的差异,其中更多"notUseful"个响应会对排名产生积极影响,而$sort会减少这种影响。根据您可以使用的MongoDB版本,您可以使用$addFields仅包含附加字段,也可以$project使用您需要返回的所有字段。

然后根据您的规则按照升级顺序对"overall"得分的组合执行"netUseful",将"useful"的新字段按降序排列为“正”到“负”。

重新建模

完全进行聚合,您可以从普通查询中获得更快的结果。但这当然意味着在向阵列添加成员时保持文档中的“得分”。

在基本选项中,您使用$inc更新运算符和$push来更改分数。

因此,对于Model.update( { "_id": docId, "useful": { "$ne": userId } }, { "$push": { "useful": userId }, "$inc": { "netUseful": 1 } }, function(err, status) { } ) 条目,您可以执行以下操作:

"notUseful"

对于Model.update( { "_id": docId, "nonUseful": { "$ne": userId } }, { "$push": { "nonUseful": userId }, "$inc": { "netUseful": -1 } }, function(err, status) { } ) 而言,你会通过“递减”而使用负值$inc执行相反的操作:

"useFul"

要涵盖所有情况,包括将投票从“{1}}”更改为"nonUseful"的情况,您可以扩展逻辑并使用{​​{3}}执行相应的反向操作。但这应该给出一般的想法。

NB 我们不在此处使用 $pull操作的原因是因为我们要确保在“时”数组中不存在用户ID递增“或”递减“。因此,$addToSet运算符用于测试不存在的值。如果是,那么我们不会尝试修改数组影响"netUseful"值。这同样适用于从用户那里“删除”用户的相反情况。

由于每次更新都会始终保持计算,因此您只需使用标准.sort()执行查询

Model.find().sort({ "overall": 1, "netUseful": -1 }).exec(function(err,results) {

})

因此,通过将“成本”移动到“投票”的维护中,您可以消除以后运行聚合的开销。对于我的钱,这是一个常规操作,并且“sort”不依赖于强制计算是动态的其他运行时参数,那么你使用存储的结果。