Dla MongoDB 3.6 i nowszych:
$expr
operator umożliwia użycie wyrażeń agregacji w języku zapytań, dzięki czemu można wykorzystać $strLenCP
operator, aby sprawdzić długość ciągu w następujący sposób:
db.usercollection.find({
"name": { "$exists": true },
"$expr": { "$gt": [ { "$strLenCP": "$name" }, 40 ] }
})
Dla MongoDB 3.4 i nowszych:
Możesz także użyć struktury agregacji z $redact
operator potoku, który umożliwia przetwarzanie warunku logicznego za pomocą $cond
operator i używa operacji specjalnych $$KEEP
aby „zachować” dokument, w którym warunek logiczny jest prawdziwy lub $$PRUNE
aby „usunąć” dokument, w którym warunek był fałszywy.
Ta operacja jest podobna do posiadania $project
potok, który wybiera pola w kolekcji i tworzy nowe pole, które przechowuje wynik zapytania o warunek logiczny, a następnie kolejne $match
, z wyjątkiem tego, że $redact
używa pojedynczego etapu potoku, który jest bardziej wydajny.
Jeśli chodzi o warunek logiczny, istnieją operatory agregacji ciągów, których można użyć $strLenCP
operator, aby sprawdzić długość ciągu. Jeśli długość to $gt
określonej wartości, to jest to prawdziwe dopasowanie, a dokument jest „zachowywany”. W przeciwnym razie jest "przycinany" i odrzucany.
Rozważ uruchomienie następującej operacji zbiorczej, która demonstruje powyższą koncepcję:
db.usercollection.aggregate([
{ "$match": { "name": { "$exists": true } } },
{
"$redact": {
"$cond": [
{ "$gt": [ { "$strLenCP": "$name" }, 40] },
"$$KEEP",
"$$PRUNE"
]
}
},
{ "$limit": 2 }
])
Jeśli używasz $where
, wypróbuj zapytanie bez nawiasów zamykających:
db.usercollection.find({$where: "this.name.length > 40"}).limit(2);
Lepszym zapytaniem byłoby sprawdzenie istnienia pola, a następnie sprawdzenie jego długości:
db.usercollection.find({name: {$type: 2}, $where: "this.name.length > 40"}).limit(2);
lub:
db.usercollection.find({name: {$exists: true}, $where: "this.name.length >
40"}).limit(2);
MongoDB ocenia inne niż $where
operacje zapytania przed $where
wyrażenia i inne niż $where
zapytania mogą używać indeksu. Dużo lepszą wydajnością jest przechowywanie długości ciągu jako innego pola, a następnie można go indeksować lub przeszukiwać; stosowanie $where
będzie znacznie wolniejszy w porównaniu do tego. Zaleca się używanie wyrażeń JavaScript i $where
operatora w ostateczności, gdy nie możesz uporządkować danych w inny sposób lub gdy masz do czynienia z niewielkim podzbiorem danych.
Inne i szybsze podejście, które pozwala uniknąć użycia $where
operatorem jest $regex
operator. Rozważ następujący wzorzec, który wyszukuje
db.usercollection.find({"name": {"$type": 2, "$regex": /^.{41,}$/}}).limit(2);
Uwaga - Z dokumentów :
Jeśli dla pola istnieje indeks, MongoDB dopasowuje wyrażenie regularne do wartości w indeksie, co może być szybsze niż skanowanie kolekcji. Dalsza optymalizacja może nastąpić, jeśli wyrażenie regularne jest „wyrażeniem przedrostkowym”, co oznacza, że wszystkie potencjalne dopasowania zaczynają się od tego samego ciągu. Dzięki temu MongoDB może skonstruować „zakres” z tego prefiksu i dopasować tylko te wartości z indeksu, które mieszczą się w tym zakresie.
Wyrażenie regularne to „wyrażenie przedrostkowe”, jeśli zaczyna się od acaret (^)
lub lewą kotwicę (\A)
, po którym następuje ciąg prostych symboli. Na przykład wyrażenie regularne /^abc.*/
zostanie zoptymalizowany przez dopasowanie tylko do wartości z indeksu zaczynających się od abc
.
Dodatkowo, gdy /^a/, /^a.*/,
i /^a.*$/
pasują do równoważnych ciągów, mają różne cechy wydajności. Wszystkie te wyrażenia używają indeksu, jeśli istnieje odpowiedni indeks; jednak /^a.*/
i /^a.*$/
są wolniejsze. /^a/
może zatrzymać skanowanie po dopasowaniu prefiksu.