Per MongoDB 3.6 e versioni successive:
Il $expr consente l'uso di espressioni di aggregazione all'interno del linguaggio di query, quindi puoi sfruttare l'uso di $strLenCP operatore per verificare la lunghezza della stringa come segue:
db.usercollection.find({
"name": { "$exists": true },
"$expr": { "$gt": [ { "$strLenCP": "$name" }, 40 ] }
})
Per MongoDB 3.4 e versioni successive:
Puoi anche utilizzare il framework di aggregazione con $redact operatore della pipeline che consente di elaborare la condizione logica con il $cond operatore e utilizza le operazioni speciali $$KEEP per "conservare" il documento in cui la condizione logica è vera o $$PRUNE per "rimuovere" il documento in cui la condizione era falsa.
Questa operazione è simile ad avere un $project pipeline che seleziona i campi nella raccolta e crea un nuovo campo che contiene il risultato della query della condizione logica e quindi un successivo $match , tranne che $redact utilizza una singola fase della pipeline che è più efficiente.
Per quanto riguarda la condizione logica, ci sono operatori di aggregazione di stringhe che puoi utilizzare $strLenCP operatore per verificare la lunghezza della stringa. Se la lunghezza è $gt un valore specificato, quindi questa è una corrispondenza vera e il documento viene "mantenuto". Altrimenti viene "potato" e scartato.
Prendi in considerazione l'esecuzione della seguente operazione di aggregazione che dimostra il concetto di cui sopra:
db.usercollection.aggregate([
{ "$match": { "name": { "$exists": true } } },
{
"$redact": {
"$cond": [
{ "$gt": [ { "$strLenCP": "$name" }, 40] },
"$$KEEP",
"$$PRUNE"
]
}
},
{ "$limit": 2 }
])
Se si utilizza $where , prova la tua query senza le parentesi quadre:
db.usercollection.find({$where: "this.name.length > 40"}).limit(2);
Una query migliore sarebbe quella di verificare l'esistenza del campo e quindi controllare la lunghezza:
db.usercollection.find({name: {$type: 2}, $where: "this.name.length > 40"}).limit(2);
oppure:
db.usercollection.find({name: {$exists: true}, $where: "this.name.length >
40"}).limit(2);
MongoDB valuta non $where operazioni di query prima di $where espressioni e non-$where le istruzioni di query possono utilizzare un indice. Una prestazione molto migliore consiste nel memorizzare la lunghezza della stringa come un altro campo e quindi è possibile indicizzarla o cercarla; applicando $where sarà molto più lento rispetto a quello. Si consiglia di utilizzare le espressioni JavaScript e il $where operatore come ultima risorsa quando non puoi strutturare i dati in altro modo o quando hai a che fare con un piccolo sottoinsieme di dati.
Un approccio diverso e più veloce che evita l'uso del $where operatore è il $regex operatore. Considera il seguente modello che cerca
db.usercollection.find({"name": {"$type": 2, "$regex": /^.{41,}$/}}).limit(2);
Nota - Dai documenti :
Se esiste un indice per il campo, MongoDB confronta l'espressione regolare con i valori nell'indice, il che può essere più veloce della scansione di una raccolta. Un'ulteriore ottimizzazione può verificarsi se l'espressione regolare è una "espressione di prefisso", il che significa che tutte le potenziali corrispondenze iniziano con la stessa stringa. Ciò consente a MongoDB di costruire un "intervallo" da quel prefisso e di confrontare solo i valori dell'indice che rientrano in quell'intervallo.
Un'espressione regolare è un'"espressione di prefisso" se inizia con acaret (^) o un'ancora a sinistra (\A) , seguito da una stringa di simplesymbols. Ad esempio, la regex /^abc.*/ sarà ottimizzato confrontando solo i valori dell'indice che iniziano con abc .
Inoltre, mentre /^a/, /^a.*/, e /^a.*$/ corrispondono a equivalentstrings, hanno caratteristiche prestazionali diverse. Tutte queste espressioni utilizzano un indice se esiste un indice appropriato; tuttavia,/^a.*/ e /^a.*$/ sono più lenti. /^a/ può interrompere la scansione dopo aver trovato la corrispondenza con il prefisso.