Próbuję użyć indeksu pokrywającego do wdrożenia wyszukiwania tekstu w mojej aplikacji, która używa mongodb.Nie można uzyskać objętego kwerendy do używania indeksu tylko w mongodb
Mam następujący zestaw index:
ensureIndex({st: 1, n: 1, _id: 1});
Ale kiedy biegnę wyjaśniać() na moje pytanie, nigdy nie mogę dostać indexOnly czytać prawdziwe, bez względu na to, co robię.
db.merchants.find({st: "Blue"}, {n:1,_id:1}).explain()
{
"cursor" : "BtreeCursor st_1_n_1__id_1",
"nscanned" : 8,
"nscannedObjects" : 8,
"n" : 8,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : true,
"indexOnly" : false,
"indexBounds" : {
"st" : [
[
"Blue",
"Blue"
]
],
"n" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"_id" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
}
}
Już się zorientowałem, że uporządkowanie kluczy w indeksie ma jakieś znaczenie. Na przykład, jeśli użyłem {_id, n: 1, st: 1}, to w ogóle nie używałem tego indeksu do wykonania zapytania. Czytałem również gdzieś, że zbyt mało dokumentów może wywołać nieprzewidywalne zachowanie za pomocą funkcji explain(), ponieważ wiele strategii jest równie szybkich. Ale w tym przypadku widzę, że używa on właściwego indeksu, ale nie używa tylko indeksu. Co się dzieje?
Używam mongoid i uważam, że mongo 2.0.8.
UPDATE:
przełączony do korzystania Mongoid v3.1.4 i mongod v2.2
Oto zapytanie, które mongod widzi od mongoid: Pon 15 lipca 10:47:26 [conn14] runQuery o nazwie spl_development.merchants {$ query: {st: {$ regex: "cr", $ options: "i"}}, $ explain: true} Pon. 15 lipca 10:47:26 [conn14] zapytanie o zapytanie spl_development.merchants: {$ query: {st: {$ regex: "cr", $ options: "i"}}, $ explain: true} ntoreturn: 0 keyApdates: 0 locks (micros) r: 212 wrócone: 1 reslen: 393 0ms
Więc projekcja nie jest wysyłana do mongody warstwa i tylko obsługuje ją w warstwie aplikacji. Nieidealny!
Zostało to uznane za błąd w mongoid i można śledzić tutaj: https://github.com/mongoid/mongoid/issues/3142
Dzięki Stennie, to dokładnie tak, "st" to tablica. Chyba zaimplementowałem to i upewniłem się, że jest to zakryte zapytanie o szybkość, muszę użyć wyrażenia regularnego w polu tekstowym, podczas gdy moja wcześniejsza strategia polegała na tym, że podzieliłem tekst na słowa w Tablicy. Mam nadzieję, że spowolnienie regex zostanie skompensowane przez fakt, że wynik jest zwracany z indeksu w pamięci. –
Możesz użyć wyrażeń regularnych, aby uczynić to zadaszonego zapytania, ale dla efektywnego użycia indeksu, regex powinien być zrootowany (np. '/^Blue /') i rozróżniana jest wielkość liter. Sprawdź wartość 'nscanned' po dodaniu wyrażenia regularnego, aby zobaczyć liczbę wymaganych porównań indeksu względem' n' (liczba zwróconych wyników). Możesz również uczynić to zapytaniem objętym zakresem, oddzielając tablice słów kluczowych na wiele dokumentów za pomocą jednego pola indeksowego. Porównałbym różne podejścia, aby zobaczyć, co najlepiej sprawdza się w twoim przypadku użycia; wielostronicowy (ale nieobjęty indeks) może być w porządku :) – Stennie
Należy również pamiętać, że ulepszona funkcja wyszukiwania tekstu (wynik, wynik, punktacja, dopasowanie fraz, słowa kończące, ..) jest opracowywana dla MongoDB 2.4 (patrz [SERVER- 380] (https://jira.mongodb.org/browse/SERVER-380)). Powinieneś być w stanie przetestować to w nadchodzącym wydaniu rozwojowym 2.3.2 (lub kompilacjach nocnych, jeśli jesteś niecierpliwy/ciekawy). Post na blogu od kogoś, kto wypróbowuje to: [MongoDB Text Search Explained] (http://blog.codecentric.de/en/2013/01/text-search-mongodb-stemming/). – Stennie