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
body
) Name,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,以决定哪种最适合你的情况。