用部分stringsearchmongoose的文本

您好我正在使用mongoosesearch我的collections中的人。

/*Person model*/ { name: { first: String, last: String } } 

现在我想用查询search人员:

 let regex = new RegExp(QUERY,'i'); Person.find({ $or: [ {'name.first': regex}, {'name.last': regex} ] }).exec(function(err,persons){ console.log(persons); }); 

如果我search约翰我得到的结果(事件,如果我search )。 但是,如果我searchJohn Doe,我显然没有得到任何结果。

如果我将QUERY更改为John | Doe,我会得到结果,但是它会返回所有在John / Doe中包含最后/名字的人员。

接下来的事情是用mongoose文本search尝试:

首先添加字段索引:

 PersonSchema.index({ name: { first: 'text', last: 'text' } },{ name: 'Personsearch index', weights: { name: { first : 10, last: 10 } } }); 

然后修改个人查询:

 Person.find({ $text : { $search : QUERY } }, { score:{$meta:'textScore'} }) .sort({ score : { $meta : 'textScore' } }) .exec(function(err,persons){ console.log(persons); }); 

这工作得很好! 但是现在只有返回的人与整个名字相匹配:

– > 约翰回报价值

– > 没有回报价值

有没有办法解决这个问题?

没有外部插件的答案是首选,但其他人也希望。

你可以用一个aggregatepipe道来做到这一点,它使用$concat连接第一个和最后一个名字,然后search:

 let regex = new RegExp(QUERY,'i'); Person.aggregate([ // Project the concatenated full name along with the original doc {$project: {fullname: {$concat: ['$name.first', ' ', '$name.last']}, doc: '$$ROOT'}}, {$match: {fullname: regex}} ], function(err, persons) { // Extract the original doc from each item persons = persons.map(function(item) { return item.doc; }); console.log(persons); }); 

性能是一个问题,但是,因为这不能使用索引,所以它将需要一个完整的收集扫描。

您可以通过在$project阶段前面添加一个$match查询来减轻这种影响,该查询可以使用索引来减lessstream水线其余部分需要查看的一组文档。

所以,如果你分别索引name.firstname.last ,然后把你的searchstring的第一个单词作为一个锚定的查询(例如/^John/i ),你可以在pipe道的开始处添加以下内容:

 {$match: $or: [ {'name.first': /^John/i}, {'name.last': /^John/i} ]} 

显然你需要编程生成“第一个字”的正则expression式,但希望它给你的想法。