mongoose – 根据分数或权重在三个字段中search文本

我在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字段上search一些文本。 到目前为止,这是我正在做的和它的工作:

 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,Body bodyName,Description,Body略less于名称和权重最小的字体。 当结果出来时,我想按照分数/重量对结果进行sorting。

到目前为止,我已经看过这个链接和权重 ,但不知道什么是获得所需结果的最佳方式。 我也想了解,我是否需要每次创build权重我search或一次性活动以及如何实现与mongoose权重?

只要你在search整个单词,一个“文本索引”和search确实是最好的select。

向模式定义添加文本索引非常简单:

 BookSchema.index( { "name": "text", "description": "text", "body": "text" }, { "weights": { "name": 5, "description": 2 } } ) 

这使您可以使用“设置”权重来执行简单的search:

 Book.find({ "$text": { "$search": "Holiday School Year" } }) .select({ "score": { "$meta": "textScore" } }) .sort({ "score": { "$meta": "textScore" } }) .exec(function(err,result) { } ); 

凡匹配的每一项将被认为是反对领域,它被发现在哪个给出最多的重量和出现次数。

赋值权重被附加到“索引”上,所以定义完成一次,不能改变。 另一个限制是在“文本search”不看“部分”的话。 例如“ci”与“City”或“Citizen”不匹配,因此您需要一个正则expression式。

如果你需要更多的灵活性,或者通常必须能够dynamic地改变结果的权重,那么你需要像聚合框架或mapReduce那样的东西。

然而,聚合框架不能执行“逻辑”匹配操作(它可以通过$match操作符进行过滤,但不能对符合条件的“正则expression式”进行“逻辑”匹配)。 如果适合,可以使用单个单词和“确切”匹配。

 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) { } ) 

作为一个聚合pipe道使用一个数据结构来查询你可以在哪里你可以改变每个exeng的权重参数到你现在需要的任何地方。

MapReduce共享一个类似的原理,你可以在主键的一部分主键中包含一个计算“分数”。 MapReduce自然地对由这个键发出的所有input进行sorting,作为一个优化来input一个reduce函数。 但是,您不能进一步sorting或“限制”这样的结果。

这些通常是你的select,以决定哪种最适合你的情况。