我在 MongoDB 之上使用 Mongoose。这就是我的模型的样子。
var BookSchema = new Schema({
name: String,
viewCount: { type: Number, default: 0 },
description: {
type: String,
default: 'No description'
},
body: {
type: String,
default: ''
}
}
});
我需要在 Name、Description、Body 字段上搜索一些文本。到目前为止,这就是我正在做的及其工作:
Book.find().or([{ 'name': { $regex: term, $options: "$i" }}, { 'description': { $regex: term, $options: "$i" }}, { 'body': { $regex: term, $options: "$i" }}]).exec(
function (err, topics) {
if (err) {
return handleError(res, err);
}
return res.status(200).json(books);
});
问题:我需要想出一些机制来为所有字段(Name,Description,Body)分配权重/分数,name 的权重最高,description 的权重略低于 name 和 body 的权重最小。当结果出来时,我想按分数/权重对结果进行排序。
到目前为止,我已经调查了这个 link & weights ,但不确定获得所需结果的最佳方法是什么。我还想了解,我是否需要在每次搜索之前创建权重,或者它是一次性事件,以及如何使用 Mongoose 实现权重?
最佳答案
A "text index"和 search只要您要搜索整个单词,这确实可能是这里的最佳选择。
将文本索引添加到您的模式定义非常简单:
BookSchema.index(
{
"name": "text",
"description": "text",
"body": "text"
},
{
"weights": {
"name": 5,
"description": 2
}
}
)
这允许您通过对字段“设置”权重来执行简单的搜索:
Book.find({ "$text": { "$search": "Holiday School Year" } })
.select({ "score": { "$meta": "textScore" } })
.sort({ "score": { "$meta": "textScore" } })
.exec(function(err,result) {
}
);
每个匹配的术语将根据找到的字段进行考虑,其中权重和出现次数最多。
分配权重是附加在“索引”上的,所以定义是一次完成的,不能更改。另一个限制是在“文本搜索”时不查看“部分”单词。例如,“ci”不匹配“City”或“Citizen”,对于这种情况,您需要一个正则表达式。
如果您需要比这更大的灵 active ,或者通常必须能够动态更改结果的权重,那么您需要聚合框架或 mapReduce 之类的东西。
然而,聚合框架无法执行 "logical" match “正则表达式”的操作(它可以通过 $match 运算符过滤,但不是“逻辑”匹配)到您的条件。如果适合,您可以使用单个单词和“精确”匹配。
Book.aggregate(
[
{ "$match": {
"$or": [
{ "name": /Holiday/ },
{ "description": /Holiday/ },
{ "body": /Holiday/ }
]
}},
{ "$project": {
"name": 1,
"description": 1,
"body": 1,
"score": {
"$add": [
{ "$cond": [{ "$eq": [ "$name", "Holiday" ] },5,0 ] },
{ "$cond": [{ "$eq": [ "$description", "Holiday" ] },2,0 ] },
{ "$cond": [{ "$eq": [ "$body", "Holiday" ] },1,0 ] }
]
}
}},
{ "$sort": { "score": -1 } }
],
function(err,results) {
}
)
由于聚合管道使用数据结构来查询,您可以在何处将每次执行的权重参数更改为您目前需要的任何值。
MapReduce 有一个类似的原则,您可以在作为前导元素发出的主键的一部分中包含计算的“分数”。 MapReduce 自然地对该键发出的所有输入进行排序,作为对 reduce 函数的优化。但是,您不能进一步排序或“限制”这样的结果。
这些通常是您查看并决定最适合您情况的选项。
关于node.js - Mongoose - 根据分数或权重在三个字段中搜索文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32063998/
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我在搜索我的值是方法的散列时遇到问题。我只是不想运行plan_type与键匹配的方法。defmethod(plan_type,plan,user){foo:plan_is_foo(plan,user),bar:plan_is_bar(plan,user),waa:plan_is_waa(plan,user),har:plan_is_har(user)}[plan_type]end目前如果我传入“bar”作为plan_type,所有方法都会运行,我怎么能只运行plan_is_bar方法呢? 最佳答案 这个变体怎么样?defmethod
我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption
我需要根据字符串路径的长度将字符串路径数组转换为符号、哈希和数组的数组给定以下数组:array=["info","services","about/company","about/history/part1","about/history/part2"]我想生成以下输出,对不同级别进行分组,根据级别的结构混合使用符号和对象。产生以下输出:[:info,:services,about:[:company,history:[:part1,:part2]]]#altsyntax[:info,:services,{:about=>[:company,{:history=>[:part1,:pa
我想获取主题名称与搜索关键字匹配的所有配置文件。现在我正在加载所有配置文件。我需要知道如何实现它。非常感谢任何帮助。配置文件.rbhas_many:categorizationshas_many:subjects,through::categorizations主题.rbhas_many:categorizationshas_many:profiles,through::categorizations分类.rbbelongs_to:profilebelongs_to:subjectviews/search/index.html.erb#searchform'get'do%>nil%>#
我有两个文本文件,master.txt和926.txt。如果926.txt中有一行不在master.txt中,我想写入一个新文件notinbook.txt。我写了我能想到的最好的东西,但考虑到我是一个糟糕的/新手程序员,它失败了。这是我的东西g=File.new("notinbook.txt","w")File.open("926.txt","r")do|f|while(line=f.gets)x=line.chompifFile.open("master.txt","w")do|h|endwhile(line=h.gets)ifline.chomp!=xputslineendende
我正在编写一个简单的日志嗅探器,它将在日志中搜索表明我支持的软件存在问题的特定错误。它允许用户指定日志路径并指定他们想要搜索多少天前。如果用户关闭日志滚动,日志文件有时会变得非常大。目前我正在做以下事情(虽然还没有完成):File.open(@log_file,"r")do|file_handle|file_handle.eachdo|line|ifline.match(/\d+++-\d+-\d+/)etc...line.match显然会查找我们在日志中使用的日期格式,其余逻辑将在下面。但是,有没有更好的方法来搜索没有.each_line的文件?如果没有,我完全同意。我只是想确保我使
我开始了一个新的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:
如何在ruby中先根据值然后根据键对散列进行排序?例如h={4=>5,2=>5,7=>1}将排序为[[7,1],[2,5],[4,5]]我可以根据值进行排序h.sort{|x,y|x[1]y[1]}但我不知道如何根据值进行排序,然后在值相同时键入 最佳答案 h.sort_by{|k,v|[v,k]}这使用了Array的事实混入Comparable并定义逐元素。注意上面等价于h.sort_by{|el|el.reverse}相当于h.sort_by(&:reverse)这可能会或可能不会更具可读性。如果你知道Hashes一般都是先