Independentemente de outras chaves de índice composto, você precisa incluir o
$meta
para o "textScore" para obter a classificação correta:db.collection.find(
{ "$text": { "$search": "\"[email protected]\""}},
{ "score": { "$meta": "textScore" } }
).sort({
"score": { "$meta": "textScore" }, "Date": 1
})
Então, naturalmente, você quer que a "pontuação" seja classificada primeiro e depois por "Data" para que as coisas sejam classificadas corretamente pela relevância da pesquisa.
A ordem do índice não importa, mas é claro que você só pode ter "um" índice de texto. Portanto, certifique-se de descartar todos os outros antes de criar:
db.collection.createIndex({
"From": "text",
"To": "text",
"CC":"text",
"BCC": "text",
"Date":1
})
Procure por índices que estão atualizados com:
db.collection.getIndicies()
Ou simplesmente largue tudo e comece de novo:
db.collection.dropIndexes()
No entanto, para os dados que você parece estar pesquisando, eu teria pensado que um índice composto regular em cada campo seria melhor para você. A procura de endereços de "e-mail" deve ser uma "correspondência exata" e, se você espera vários itens para cada campo, eles devem ser matrizes de strings, assim:
{
"TO": ["[email protected]"],
"FROM": ["[email protected]"],
"CC": ["[email protected]","[email protected]"],
"BCC": [],
"Date": ISODate("2015-07-27T13:42:05.535Z")
}
Então você precisa de índices separados em cada campo, possivelmente em composto com "Data" assim:
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 })
E consulte com um
$or
doença:db.email.find({
"$or": [
{ "TO": "[email protected]" },
{ "FROM": "[email protected]" },
{ "CC": "[email protected]" },
{ "BCC": "[email protected]" }
],
"Date": { "$lt": new Date() }
})
Se você olhar para o
.explain(true)
(verbose) a partir disso, você deve ver que o plano vencedor é uma "interseção de índice" de todos os índices especificados. Isso funciona para ser muito eficiente, pois cada campo (e índice selecionado) tem um valor de correspondência exata e uma correspondência de intervalo na data indexada. Isso será muito melhor para você do que a "correspondência difusa" das pesquisas de texto. Mesmo as expressões regulares devem funcionar melhor aqui em geral ( para endereços de e-mail ) e especialmente se estiverem "ancoradas"
^
para o início da string. Índices de texto destinam-se à correspondência de "tokens semelhantes a palavras", mas esses não devem ser seus dados. O
$or
não parece bom, mas deve fazer um trabalho muito melhor.