Aby uzyskać jak najwięcej z indeksu, musisz odpowiednio wcześnie przygotować $match, które wykorzysta wszystkie pola w indeksie. I unikaj używania $and
operatora, ponieważ jest to niepotrzebne i w obecnej wersji (2.4) może spowodować, że indeks nie zostanie w pełni wykorzystany (na szczęście naprawiony w nadchodzącym 2.6).
Jednak zapytanie nie jest całkiem poprawne, ponieważ musisz użyć $elemMatch
aby upewnić się, że ten sam element jest używany do wypełnienia pól nazwy i wartości.
Twoje zapytanie powinno brzmieć:
db.Phone.aggregate([
{$match: { type: "Samsung",
attributes: { $all: [
{$elemMatch: {"value":"100", "type" : "BatteryLife" }},
{$elemMatch: {"value":"200$", "type" : "Price" }}
] }
}
}]);
Teraz to nie będzie ukrytym zapytaniem, ponieważ atrybuty.wartość i nazwa są osadzone, nie wspominając o tym, że nazwy nie ma w indeksie.
Potrzebujesz indeksu w postaci {"type":1, "attributes.value":1, "attributes.name":1}
dla najlepszej wydajności, choć nadal nie zostanie to omówione, będzie znacznie bardziej selektywne niż teraz.