我有一个约会应用程序,我将所有潜在的 Match 对象存储在 MongoDB 中(当用户向左或向右滑动时会发生 Match 对象):
{
uid1: <userid1>,
uid2: <userid2>,
uid1action: <L|R|E> (left/right/empty, based what the user1 has done),
uid2action: <L|R|E> (left/right/empty, based what the user2 has done),
}
现在是我的问题。当我向 user1 显示潜在用户的个人资料时,我会考虑所有已经喜欢 user1 的人(因为我优先考虑这些个人资料):
var likedQuery = Parse.Query.or(new Parse.Query("Match")
.equalTo("uid1", userId)
.equalTo("u2action", "L")
.equalTo("u1action", "E") // user1 has not done anything
.select("uid2")
.limit(paginationLimit);
现在很好,一切正常。我现在还希望根据每个用户的点赞数(受欢迎程度)来对 LikedQuery 进行排序。
说这些是喜欢user1的以下用户:
保罗(保罗本人有 50 个人像他一样)
Logan(Logan 被 20 人点赞)
迈克尔(迈克尔被 80 人点赞),
我们希望对所有这些人进行排序,以便 Michael 成为 user1 看到的第一个个人资料。
现在我的问题是,我将如何使用 mongoDB?在 SQL 中这很简单,只需做一个表 JOIN,使用 SUM() 和 COUNT() 按该表排序,并确保您有必要的索引。
在 mongoDB 中,我看到如何做到这一点的唯一方法是在每个 Match 对象上都有一个 uid2likes (将对其进行排序)字段,该字段将由 cron 作业递增,但那是荒谬且无法扩展。
我的问题更多是关于如何以可扩展的方式做到这一点。
最佳答案
您可以在 3.4 中使用以下聚合查询。
这里的想法是$match所有喜欢user1的用户都喜欢自己$lookup获取所有喜欢user1的用户。
$group和 $sort按 count desc 对匹配项进行排序。
$limit限制匹配的用户。
db.colname.aggregate([
{"$match":{"uid1":userID,"uid2action":"L","uid1action":"E"}},
{"$lookup":{
"from":colname,
"localField":"uid2",
"foreignField":"uid1",
"as":"uid2likes"
}},
{"$unwind":"$uid2likes"},
{"$match":{"uid2likes.uid2action":"L"}},
{"$group":{
"_id":{"uid1":"$uid1","uid2":"$uid2"},
"uid2likecount":{"$sum":1}
}},
{"$sort":{"uid2likecount":-1}},
{"$limit":paginationLimit}
])
几个笔记
使用 $lookup + $unwind + $match 很重要在 3.4 中优化为通过移动查询谓词 $match 运行里面 $lookup .更多 here
您可以使用现有索引(假设您在 uid1 上有一个)进行初始匹配和查找匹配。
还可以尝试在 uid2action 上添加索引,看看它是否被 $lookup 拾取+ $match阶段。更多 here 和 here
添加索引:
db.colname.createIndex( { uid1: 1 } )
db.colname.createIndex( { uid2action: 1 } )
衡量指标使用:
db.colname.aggregate([{$indexStats: {}}, {$project: {key: 0, host: 0}}]).pretty();
解释查询:
db.colname.explain("executionStats").aggregate(above pipeline);
您可以在索引之间交替并检查执行统计信息以查看索引是如何被拾取的。也尝试复合索引。
使用 3.6 可以稍微清理一下查询。
db.colname.aggregate([
{"$match":{"uid1":userID,"uid2action":"L","uid1action":"E"}},
{"$lookup":{
"from":colname,
"let":{"uid2":"$uid2"},
"pipeline":[
{"$match":{"$expr":{"$eq":["$uid1","$$uid2"]},"uid2action":"L"}},
{"$count":"count"}
],
"as":"uid2likes"
}},
{"$unwind":"$uid2likes"},
{"$sort":{"uid2likes.count":-1}},
{"$limit":paginationLimit}
])
关于MongoDB按二级查找表排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53053567/
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or
我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s
我有一个应用需要发送用户事件邀请。当用户邀请friend(用户)参加事件时,如果尚不存在将用户连接到该事件的新记录,则会创建该记录。我的模型由用户、事件和events_user组成。classEventdefinvite(user_id,*args)user_id.eachdo|u|e=EventsUser.find_or_create_by_event_id_and_user_id(self.id,u)e.save!endendend用法Event.first.invite([1,2,3])我不认为以上是完成我的任务的最有效方法。我设想了一种方法,例如Model.find_or_cr
我需要用任何语言编写一个算法,根据3个因素对数组进行排序。我以度假村为例(如Hipmunk)。假设我想去度假。我想要最便宜的地方、最好的评论和最多的景点。但是,显然我找不到在所有3个中都排名第一的方法。Example(assumingthereare20importantattractions):ResortA:$150/night...98/100infavorablereviews...18of20attractionsResortB:$99/night...85/100infavorablereviews...12of20attractionsResortC:$120/night
我正在尝试按Rails相关模型中的字段进行排序。我研究的所有解决方案都没有解决如果相关模型被另一个参数过滤?元素模型classItem相关模型:classPriority我正在使用where子句检索项目:@items=Item.where('company_id=?andapproved=?',@company.id,true).all我需要按相关表格中的“位置”列进行排序。问题在于,在优先级模型中,一个项目可能会被多家公司列出。因此,这些职位取决于他们拥有的company_id。当我显示项目时,它是针对一个公司的,按公司内的职位排序。完成此任务的正确方法是什么?感谢您的帮助。PS-我
我想找到给定字符串中的所有匹配项,包括重叠匹配项。我怎样才能实现它?#Example"a-b-c-d".???(/\w-\w/)#=>["a-b","b-c","c-d"]expected#Solutionwithoutoverlappedresults"a-b-c-d".scan(/\w-\w/)#=>["a-b","c-d"],but"b-c"ismissing 最佳答案 在积极的前瞻中使用捕获:"a-b-c-d".scan(/(?=(\w-\w))/).flatten#=>["a-b","b-c","c-d"]参见Rubyde
我正在构建一个小部件来显示奥运会的奖牌数。我有一个“国家”对象的集合,其中每个对象都有一个“名称”属性,以及奖牌计数的“金”、“银”、“铜”。列表应该排序:1.首先是奖牌总数2.如果奖牌相同,按类型分割(金>银>铜,即2金>1金+1银)3.如果奖牌和类型相同,则按字母顺序子排序我正在用ruby做这件事,但我想语言并不重要。我确实找到了一个解决方案,但如果感觉必须有更优雅的方法来实现它。这是我做的:使用加权奖牌总数创建一个虚拟属性。因此,如果他们有2个金牌和1个银牌,加权总数将为“3.020100”。1金1银1铜为“3.010101”由于我们希望将奖牌数排序为最高的,因此列表按降序排
这应该是一个简单的问题,但我找不到任何相关信息。给定一个Ruby中的正则表达式,对于每个匹配项,我需要检索匹配的模式$1、$2,但我还需要匹配位置。我知道=~运算符为我提供了第一个匹配项的位置,而string.scan(/regex/)为我提供了所有匹配模式。如果可能,我需要在同一步骤中获得两个结果。 最佳答案 MatchDatastring.scan(regex)do$1#Patternatfirstposition$2#Patternatsecondposition$~.offset(1)#Startingandendingpo
例如,假设我有一个名为Products的模型,并且在ProductsController中,我有以下代码用于product_listView以显示已排序的产品。@products=Product.order(params[:order_by])让我们想象一下,在product_listView中,用户可以使用下拉菜单按价格、评级、重量等进行排序。数据库中的产品不会经常更改。我很难理解的是,每次用户选择新的order_by过滤器时,rails是否必须查询,或者rails是否能够以某种方式缓存事件记录以在服务器端重新排序?有没有一种方法可以编写它,以便在用户排序时rails不会重新查询结果
我有一个帖子属于城市的关系,城市又属于一个州,例如:classPost现在我想找到所有帖子及其所属的城市和州。我编写了以下查询来获取带有城市的帖子,但不知道如何在同一查找器中获取带有城市的相应州:@post=Post.find:all,:include=>[:city]感谢任何帮助。谢谢。 最佳答案 Post.all(:include=>{:city=>:state}) 关于ruby-on-rails-使用Rails事件记录获取二级模型,我们在StackOverflow上找到一个类似的问