我正在尝试从 Node 上的 MongoDB 获取文档。假设文档具有以下结构:
{ "_id": ObjectId, "title" : String, "tags" : Array<String> }
我想按相关性对它们进行排序 - 因此,当我查找具有“蓝色”或“黄色”标签的文档时,我希望首先找到具有这两个标签的文档。到目前为止,我通过谷歌管理,反复试验:
var tags = [ "yellow", "blue" ];
db.collection('files').aggregate([
{ $project : { tags: 1 } },
{ $unwind : "$tags" },
{ $match : { "tags": { "$in": tags } } },
{ $group : { _id: "$_id", relevance: { $sum:1 } } },
{ $sort : { relevance : -1 } },
], function(err, success) {
console.log(success);
});
它工作得很好,我得到了 id 的排序集合:
[{"_id":"5371355045002fc820a09566","relevance":2},{"_id":"53712fc6c8fcd124216de6cd","relevance":2},{"_id":"5371302ebd4725dc1b908316","relevance":1}]
现在我将进行另一个查询并询问具有这些 ID 的文档 - 但这是我的问题:可以在一个查询中完成吗?
最佳答案
是的,当您实际根据 _id 进行分组时,您可以像往常一样,那么该值基本上等同于整个文档。所以这只是将整个文档存储在 _id 字段下的问题。
根据您的 MongoDB 版本,您可以采用多种方法,在 MongoDB 2.6 之前的版本中,您必须在初始 $project 中指定整个文档结构。在实际操作文档之前,管道中的阶段(可以选择在 $match 之后,这通常是个好主意):
var tags = ["yellow","blue"];
db.collection.aggregate([
{ "$project" : {
"_id": {
"_id": "$_id",
"title": "$title",
"tags": "$tags"
},
"tags": 1
}},
{ "$unwind": "$tags" },
{ "$match": { "tags": { "$in": tags } } },
{ "$group": { "_id": "$_id", "relevance": { "$sum":1 } } },
{ "$sort": { "relevance" : -1 } },
{ "$project": {
_id: "$_id._id",
"title": "$_id.title",
"tags": "$_id.tags"
}}
])
当然,在管道的末尾,您从 _id 字段中提取信息以取回您的原始结构。这是可选的,但您通常需要它。
对于 MongoDB 2.6 及更高版本,有一个变量可用于管道阶段,该变量保存管道该阶段的文档结构,称为 $$ROOT。 ,您可以像这样访问它作为上述表单的一种快捷方式:
var tags = ["yellow","blue"];
db.collection.aggregate([
{ "$project" : {
"_id": "$$ROOT",
"tags": 1
}},
{ "$unwind": "$tags" },
{ "$match": { "tags": { "$in": tags } } },
{ "$group": { "_id": "$_id", "relevance": { "$sum":1 } } },
{ "$sort": { "relevance" : -1 } },
{ "$project": {
"_id": "$_id._id",
"title": "$_id.title",
"tags": "$_id.tags"
}}
])
请记住,为了恢复文档,您仍然需要指定所有必填字段。
我会注意到,在这种情况下,正如前面提到的,当您使用匹配条件“过滤”文档时,您实际上应该使用 $match 进行过滤。在管道的“头部”声明。这是聚合框架唯一可以选择索引以优化查询的地方,它还减少了不符合您条件的文档的数量(假设不是所有的东西都有标签“黄色”或“蓝色”)通过剩余的流水线阶段:
db.collection.aggregate([
{ "$match": { "tags": { "$in": tags } } },
{ "$project" : {
"_id": {
"_id": "$_id",
"title": "$title",
"tags": "$tags"
},
"tags": 1
}},
{ "$unwind": "$tags" },
{ "$match": { "tags": { "$in": tags } } },
{ "$group": { "_id": "$_id", "relevance": { "$sum":1 } } },
{ "$sort": { "relevance" : -1 } },
{ "$project": {
_id: "$_id._id",
"title": "$_id.title",
"tags": "$_id.tags"
}}
])
无论如何,这通常比尝试执行另一个查询更有效,后者当然不会按照您所做的方式维护您的排序顺序。
关于node.js - MongoDB 按相关性排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23641752/
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
我需要用任何语言编写一个算法,根据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-我
我正在构建一个小部件来显示奥运会的奖牌数。我有一个“国家”对象的集合,其中每个对象都有一个“名称”属性,以及奖牌计数的“金”、“银”、“铜”。列表应该排序:1.首先是奖牌总数2.如果奖牌相同,按类型分割(金>银>铜,即2金>1金+1银)3.如果奖牌和类型相同,则按字母顺序子排序我正在用ruby做这件事,但我想语言并不重要。我确实找到了一个解决方案,但如果感觉必须有更优雅的方法来实现它。这是我做的:使用加权奖牌总数创建一个虚拟属性。因此,如果他们有2个金牌和1个银牌,加权总数将为“3.020100”。1金1银1铜为“3.010101”由于我们希望将奖牌数排序为最高的,因此列表按降序排
例如,假设我有一个名为Products的模型,并且在ProductsController中,我有以下代码用于product_listView以显示已排序的产品。@products=Product.order(params[:order_by])让我们想象一下,在product_listView中,用户可以使用下拉菜单按价格、评级、重量等进行排序。数据库中的产品不会经常更改。我很难理解的是,每次用户选择新的order_by过滤器时,rails是否必须查询,或者rails是否能够以某种方式缓存事件记录以在服务器端重新排序?有没有一种方法可以编写它,以便在用户排序时rails不会重新查询结果
我有一个对象如下:[{:id=>2,:fname=>"Ron",:lname=>"XXXXX",:photo=>"XXX"},{:id=>3,:fname=>"Dain",:lname=>"XXXX",:photo=>"XXXXXXX"},{:id=>1,:fname=>"Bob",:lname=>"XXXXXX",:photo=>"XXXX"}]我想按fname排序,不区分大小写,所以它会导致编号:1,3,2我该如何排序?我正在尝试:@people.sort!{|x,y|y[:fname]x[:fname]}但这没有任何效果。 最佳答案
我开始了一个新的Rails3.2.5项目,Assets管道不再工作了。CSS和Javascript文件不再编译。这是尝试生成Assets时日志的输出:StartedGET"/assets/application.css?body=1"for127.0.0.1at2012-06-1623:59:11-0700Servedasset/application.css-200OK(0ms)[2012-06-1623:59:11]ERRORNoMethodError:undefinedmethod`each'fornil:NilClass/Users/greg/.rbenv/versions/1
rails新手。只是想了解\assests目录中的这两个文件。例如,application.js文件有如下行://=requirejquery//=requirejquery_ujs//=require_tree.我理解require_tree。只是将所有JS文件添加到当前目录中。根据上下文,我可以看出requirejquery添加了jQuery库。但是它从哪里得到这些jQuery库呢?我没有在我的Assets文件夹中看到任何jquery.js文件——或者直接在我的整个应用程序中没有看到任何jquery.js文件?同样,我正在按照一些说明安装TwitterBootstrap(http:
有人可以告诉我如何根据自定义字符串对嵌套数组进行排序吗?比如有没有办法排序:[['Red','Blue'],['Green','Orange'],['Purple','Yellow']]“橙色”、“黄色”,然后是“蓝色”?最终结果如下所示:[['Green','Orange'],['Purple','Yellow'],['Red','Blue']]它不是按字母顺序排序的。我很想知道我是否可以定义要排序的值以实现上述目标。 最佳答案 sort_by对于这种排序总是非常方便:a=[['Red','Blue'],['Green','Ora
我有以下现有的Dog对象数组,它们按age属性排序:classDogattr_accessor:agedefinitialize(age)@age=ageendenddogs=[Dog.new(1),Dog.new(4),Dog.new(10)]我现在想插入一条新的狗记录,并将它放在数组中的正确位置。假设我想插入这个对象:another_dog=Dog.new(8)我想把它插入到数组中,让它成为数组中的第三项。这是一个人为的示例,旨在演示我特别想如何将一个项目插入到现有的有序数组中。我意识到我可以创建一个全新的数组并重新对所有对象进行排序,但这不是我的目标。谢谢!