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.