带有部分字符串的猫鼬文本搜索
Posted
技术标签:
【中文标题】带有部分字符串的猫鼬文本搜索【英文标题】:Mongoose text-search with partial string 【发布时间】:2016-05-11 04:33:09 【问题描述】:您好,我正在使用 mongoose 来搜索我收藏中的人。
/*Person model*/
name:
first: String,
last: String
现在我想搜索有查询的人:
let regex = new RegExp(QUERY,'i');
Person.find(
$or: [
'name.first': regex,
'name.last': regex
]
).exec(function(err,persons)
console.log(persons);
);
如果我搜索 John,我会得到结果(如果我搜索 Jo,则会发生事件)。 但是,如果我搜索 John Doe,我显然没有得到任何结果。
如果我将 QUERY 更改为 John|Doe 我会得到结果,但它会返回所有拥有 John 或 Doe 的人 在他们的姓/名中。
接下来是尝试使用 mongoose 文本搜索:
首先将字段添加到索引:
PersonSchema.index(
name:
first: 'text',
last: 'text'
,
name: 'Personsearch index',
weights:
name:
first : 10,
last: 10
);
然后修改Person查询:
Person.find(
$text :
$search : QUERY
,
score:$meta:'textScore' )
.sort( score : $meta : 'textScore' )
.exec(function(err,persons)
console.log(persons);
);
这很好用! 但是现在只返回与整个名字/姓氏匹配的人:
-> John 返回值
-> Jo 不返回任何值
有没有办法解决这个问题?
没有外部插件的答案是首选,但也希望其他答案。
【问题讨论】:
您可能需要为此使用 Elasticsearch。如果您愿意,我可以为您提供详细的代码。为了获得全名搜索,您应该以 \"query"\ 格式输入查询。 只用猫鼬进行部分搜索是行不通的。在选择弹性之前,我尝试了 3 天。 感谢您的提示,但对于这种情况,Elastiq 似乎有点过分了。如果有可能将名字和姓氏合并到一个字段中(仅用于一个查询),然后使用正则表达式进行搜索就可以了。但是我不确定猫鼬是否可以做到这一点? 所以您需要自动完成(通配符查询,如“phrase*”)名字和姓氏,但想分别存储? 请看:virtuals 可以合并两个字段。 【参考方案1】:您可以使用aggregate
管道来执行此操作,该管道使用$concat
将名字和姓氏连接在一起,然后对其进行搜索:
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
查询来缓解这种情况,可以使用索引来减少管道其余部分需要查看的文档集。 p>
因此,如果您分别索引name.first
和name.last
,然后将搜索字符串的第一个单词作为锚定查询(例如/^John/i
),您可以在管道开头添加以下内容:
$match: $or: [
'name.first': /^John/i,
'name.last': /^John/i
]
显然,您需要以编程方式生成“第一个单词”正则表达式,但希望它能给您带来想法。
【讨论】:
这种正则表达式方法在大规模上表现是否足够好?【参考方案2】:正则表达式可以帮助您。
Person.find( "name": "$regex": "Alex", "$options": "i" ,
function(err,docs)
);
【讨论】:
你在哪里找到这个文档? 我浏览了一些帖子。我不完全记得它们,但它经过试验和测试。您可以在代码中使用它。 有效,但除了这里,我在任何地方都找不到这个文档。谢谢!! @TJBlackman 虽然这是关于 Mongoose 的问题,但 $regex 运算符是 Mongoose 用来查询集合的 Mongo 运算符。 docs.mongodb.com/manual/reference/operator/query/regex【参考方案3】:一)。 在集合中的单个字段中进行部分文本搜索:
如果我们想在集合中的单个字段中搜索,我们可以使用聚合代码
$match:
name:
$regex: “String seraching”,
‘$options’: ‘i’
b)。 通过集合中的多个字段进行部分文本搜索:
如果我们想在特定集合中搜索多个字段(多个字段),那么我们可以在聚合查询中使用该代码
$match:
$or: [
name:
$regex: “String to be searched”,
‘$options’: ‘i’
,
email:
$regex: String to be searched,
‘$options’: ‘i’
]
,
【讨论】:
以上是关于带有部分字符串的猫鼬文本搜索的主要内容,如果未能解决你的问题,请参考以下文章