草庐IT

node.js - Mongoose - 根据分数或权重在三个字段中搜索文本

coder 2023-11-03 原文

我在 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/

有关node.js - Mongoose - 根据分数或权重在三个字段中搜索文本的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. ruby-on-rails - 使用作为方法的值在 ruby​​ 中搜索哈希 - 2

    我在搜索我的值是方法的散列时遇到问题。我只是不想运行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

  3. ruby - 如何使用 Selenium Webdriver 根据 div 的内容执行操作? - 2

    我有一个使用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

  4. ruby - 如何根据长度将路径数组转换为嵌套数组或散列 - 2

    我需要根据字符串路径的长度将字符串路径数组转换为符号、哈希和数组的数组给定以下数组: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

  5. ruby-on-rails - 如何在 Rails 4 中搜索关联 - 2

    我想获取主题名称与搜索关键字匹配的所有配置文件。现在我正在加载所有配置文件。我需要知道如何实现它。非常感谢任何帮助。配置文件.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%>#

  6. ruby - 尝试比较两个文本文件,并根据信息创建第三个 - 2

    我有两个文本文件,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

  7. ruby - 在 Ruby 中搜索大文件的更简单方法? - 2

    我正在编写一个简单的日志嗅探器,它将在日志中搜索表明我支持的软件存在问题的特定错误。它允许用户指定日志路径并指定他们想要搜索多少天前。如果用户关闭日志滚动,日志文件有时会变得非常大。目前我正在做以下事情(虽然还没有完成):File.open(@log_file,"r")do|file_handle|file_handle.eachdo|line|ifline.match(/\d+++-\d+-\d+/)etc...line.match显然会查找我们在日志中使用的日期格式,其余逻辑将在下面。但是,有没有更好的方法来搜索没有.each_line的文件?如果没有,我完全同意。我只是想确保我使

  8. ruby-on-rails - Assets 管道损坏 : Not compiling on the fly css and js files - 2

    我开始了一个新的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

  9. ruby-on-rails - Rails - 理解 application.js 和 application.css - 2

    rails新手。只是想了解\assests目录中的这两个文件。例如,application.js文件有如下行://=requirejquery//=requirejquery_ujs//=require_tree.我理解require_tree。只是将所有JS文件添加到当前目录中。根据上下文,我可以看出requirejquery添加了jQuery库。但是它从哪里得到这些jQuery库呢?我没有在我的Assets文件夹中看到任何jquery.js文件——或者直接在我的整个应用程序中没有看到任何jquery.js文件?同样,我正在按照一些说明安装TwitterBootstrap(http:

  10. ruby - 根据值然后键对ruby中的哈希进行排序 - 2

    如何在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一般都是先

随机推荐