无论其他复合索引键如何,您都需要包含$meta http://docs.mongodb.org/manual/reference/operator/projection/meta/#proj._S_meta对于“textScore”以获得正确的排序:
db.collection.find(
{ "$text": { "$search": "\"[email protected] /cdn-cgi/l/email-protection\""}},
{ "score": { "$meta": "textScore" } }
).sort({
"score": { "$meta": "textScore" }, "Date": 1
})
因此,您自然希望首先按“分数”排序,然后按“日期”排序,以便根据搜索的相关性对事物进行正确排名。
索引的顺序并不重要,但当然你只能有“一个”文本索引。因此,请确保在创建之前删除所有其他内容:
db.collection.createIndex({
"From": "text",
"To": "text",
"CC":"text",
"BCC": "text",
"Date":1
})
查找当前的索引:
db.collection.getIndicies()
或者干脆放弃一切并重新开始:
db.collection.dropIndexes()
对于您似乎正在搜索的数据,我认为每个字段的常规复合索引应该更适合您。查找“电子邮件”地址应该是“完全匹配”,如果您期望每个字段有多个项目,那么它们应该是字符串数组,如下所示:
{
"TO": ["[email protected] /cdn-cgi/l/email-protection"],
"FROM": ["[email protected] /cdn-cgi/l/email-protection"],
"CC": ["[email protected] /cdn-cgi/l/email-protection","[email protected] /cdn-cgi/l/email-protection"],
"BCC": [],
"Date": ISODate("2015-07-27T13:42:05.535Z")
}
然后,您需要在每个字段上使用单独的索引,可以与“日期”复合,如下所示:
db.email.createIndex({ "TO": 1, "Date": 1 })
db.email.createIndex({ "FROM": 1, "Date": 1 })
db.email.createIndex({ "CC": 1, "Date": 1 })
db.email.createIndex({ "BCC": 1, "Date": 1 })
并用一个查询$or http://docs.mongodb.org/manual/reference/operator/query/or/健康)状况:
db.email.find({
"$or": [
{ "TO": "[email protected] /cdn-cgi/l/email-protection" },
{ "FROM": "[email protected] /cdn-cgi/l/email-protection" },
{ "CC": "[email protected] /cdn-cgi/l/email-protection" },
{ "BCC": "s[email protected] /cdn-cgi/l/email-protection" }
],
"Date": { "$lt": new Date() }
})
如果你看一下.explain(true) http://docs.mongodb.org/manual/reference/method/cursor.explain/(详细)输出,您应该看到获胜计划是所有指定索引的“索引交集”。这非常有效,因为每个字段(和选定的索引)都有一个精确匹配值,以及索引日期的范围匹配。
这比文本搜索的“模糊匹配”对您来说要好得多。一般来说,甚至正则表达式在这里也应该工作得更好(对于电子邮件地址),特别是如果它们是“锚定的”^
到字符串的开头。
文本索引用于匹配“类似单词的标记”,但这不应该是您的数据。这$or
看起来不太好,但它应该做得更好。