Uanset andre sammensatte indeksnøgler skal du inkludere $meta
for "textScore" for at få den korrekte sortering:
db.collection.find(
{ "$text": { "$search": "\"[email protected]\""}},
{ "score": { "$meta": "textScore" } }
).sort({
"score": { "$meta": "textScore" }, "Date": 1
})
Så naturligvis vil du have, at "score" skal sorteres først og derefter efter "Dato", for at tingene bliver korrekt rangeret efter søgningens relevans.
Indeksrækkefølgen er ligegyldig, men du kan selvfølgelig kun have "et" tekstindeks. Så sørg for at droppe alle andre, før du opretter:
db.collection.createIndex({
"From": "text",
"To": "text",
"CC":"text",
"BCC": "text",
"Date":1
})
Se efter indekser, der er aktuelle med:
db.collection.getIndicies()
Eller bare slip alt og start på en frisk:
db.collection.dropIndexes()
For de data, du ser ud til at søge på, ville jeg dog have troet, at et almindeligt sammensat indeks på hvert felt burde passe dig bedre. At lede efter "e-mail"-adresser bør være et "nøjagtigt match", og hvis du forventer flere elementer for hvert felt, skal de være arrays af strenge, som sådan:
{
"TO": ["[email protected]"],
"FROM": ["[email protected]"],
"CC": ["[email protected]","[email protected]"],
"BCC": [],
"Date": ISODate("2015-07-27T13:42:05.535Z")
}
Så har du brug for separate indekser på hvert felt, muligvis sammensat med "Dato" som sådan:
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 })
Og forespørg med en $or
tilstand:
db.email.find({
"$or": [
{ "TO": "[email protected]" },
{ "FROM": "[email protected]" },
{ "CC": "[email protected]" },
{ "BCC": "[email protected]" }
],
"Date": { "$lt": new Date() }
})
Hvis du ser på .explain(true)
(verbose) output fra det, bør du se, at den vindende plan er et "indeks skæringspunkt" af alle de specificerede indekser. Dette viser sig at være meget effektivt, da hvert felt (og det valgte indeks) har en nøjagtig matchværdi og et intervalmatch på den indekserede dato.
Det vil være meget bedre for dig end den "fuzzy matching" af tekstsøgninger. Selv regulære udtryk burde fungere bedre her generelt (for e-mail-adresser) og især hvis de er "forankrede" ^
til begyndelsen af strengen.
Tekstindekser er beregnet til, at "ordlignende tokens" skal matche, men dette bør ikke være dine data. $or
ser ikke pænt ud, men det burde gøre et meget bedre stykke arbejde.