Niezależnie od innych złożonych kluczy indeksowych, musisz uwzględnić $meta
dla "textScore", aby uzyskać prawidłowe sortowanie:
db.collection.find(
{ "$text": { "$search": "\"[email protected]\""}},
{ "score": { "$meta": "textScore" } }
).sort({
"score": { "$meta": "textScore" }, "Date": 1
})
Więc naturalnie chcesz, aby ten „wynik” został najpierw posortowany, a następnie według „daty”, aby rzeczy były prawidłowo uszeregowane według trafności wyszukiwania.
Kolejność indeksu nie ma znaczenia, ale oczywiście możesz mieć tylko "jeden" indeks tekstowy. Więc upewnij się, że upuściłeś wszystkie inne przed utworzeniem:
db.collection.createIndex({
"From": "text",
"To": "text",
"CC":"text",
"BCC": "text",
"Date":1
})
Poszukaj indeksów, które są aktualne z:
db.collection.getIndicies()
Lub po prostu rzuć wszystko i zacznij od nowa:
db.collection.dropIndexes()
W przypadku danych, które wydajesz, że szukasz, pomyślałbym, że zwykły indeks złożony w każdym polu powinien ci lepiej odpowiadać. Szukanie adresów „e-mail” powinno być „dokładnym dopasowaniem”, a jeśli oczekujesz wielu elementów w każdym polu, powinny to być tablice ciągów, jak na przykład:
{
"TO": ["[email protected]"],
"FROM": ["[email protected]"],
"CC": ["[email protected]","[email protected]"],
"BCC": [],
"Date": ISODate("2015-07-27T13:42:05.535Z")
}
Następnie potrzebujesz oddzielnych indeksów w każdym polu, prawdopodobnie w połączeniu z "Date", jak na przykład:
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 })
I zapytanie za pomocą $or
warunek:
db.email.find({
"$or": [
{ "TO": "[email protected]" },
{ "FROM": "[email protected]" },
{ "CC": "[email protected]" },
{ "BCC": "[email protected]" }
],
"Date": { "$lt": new Date() }
})
Jeśli spojrzysz na .explain(true)
(pełne) wyjście z tego, powinieneś zobaczyć, że zwycięski plan jest "przecięciem indeksu" wszystkich określonych indeksów. Jest to bardzo wydajne, ponieważ każde pole (i wybrany indeks) ma dokładne dopasowanie wartości i dopasowanie zakresu w zindeksowanej dacie.
To będzie dla Ciebie o wiele lepsze niż „rozmyte dopasowanie” wyszukiwań tekstowych. Nawet wyrażenia regularne powinny ogólnie działać lepiej (dla adresów e-mail), a zwłaszcza jeśli są "zakotwiczone" ^
na początek ciągu.
Indeksy tekstowe są przeznaczone do dopasowania „tokenów podobnych do słów”, ale nie powinny to być Twoje dane. $or
nie wygląda ładnie, ale powinien działać znacznie lepiej.