strlencp length len mongodb field string-length

length - Longitud del valor del campo de cadena en mongoDB



mongodb where length (4)

El tipo de datos del campo es Cadena. Me gustaría obtener los datos donde la longitud de los caracteres del nombre del campo es mayor que 40.

Intenté estas consultas pero devolví el error. 1)

db.usercollection.find( {$where: "(this.name.length > 40)"} ).limit(2); output :error: { "$err" : "TypeError: Cannot read property ''length'' of undefined near ''40)'' ", "code" : 16722 }

esto funciona en 2.4.9 Pero mi versión es 2.6.5


Esta es una de las formas en que mongodb puede lograr esto.

db.usercollection.find({ $where: ''this.name.length < 4'' })


Las consultas con $where y $expr son lentas si hay demasiados documentos.

Usar $regex es mucho más rápido que $where , $expr .

db.usercollection.find({ "name": /^[/s/S]{40,}$/, // name.length >= 40 }) or db.usercollection.find({ "name": { "$regex": "^[/s/S]{40,}$" }, // name.length >= 40 })

Esta consulta tiene el mismo significado con

db.usercollection.find({ "$where": "this.name && this.name.length >= 40", }) or db.usercollection.find({ "name": { "$exists": true }, "$expr": { "$gte": [ { "$strLenCP": "$name" }, 40 ] } })

Probé cada consulta para mi colección.

# find $where: 10529.359ms $expr: 5305.801ms $regex: 2516.124ms # count $where: 10872.006ms $expr: 2630.155ms $regex: 158.066ms


Tuve un tipo similar de escenario, pero en mi caso la cadena no es un atributo de primer nivel. Está dentro de un objeto. Aquí no pude encontrar una respuesta adecuada para ello. Así que pensé en compartir mi solución con todos ustedes (espero que esto ayude a cualquiera con un tipo de problema similar).

Parent Collection { "Child": { "name":"Random Name", "Age:"09" } }

Ej: si necesitamos obtener solo colecciones que tengan la longitud del nombre del niño mayor de 10 caracteres.

db.getCollection(''Parent'').find({$where: function() { for (var field in this.Child.name) { if (this.Child.name.length > 10) return true; } }})


Para MongoDB 3.6 y más reciente:

El operador $expr permite el uso de expresiones de agregación dentro del lenguaje de consulta, por lo tanto, puede aprovechar el uso del operador $strLenCP para verificar la longitud de la cadena de la siguiente manera:

db.usercollection.find({ "name": { "$exists": true }, "$expr": { "$gt": [ { "$strLenCP": "$name" }, 40 ] } })

Para MongoDB 3.4 y más reciente:

También puede usar el marco de agregación con el operador de canalización $redact que le permite procesar la condición lógica con el operador $cond y usa las operaciones especiales $$KEEP para "mantener" el documento donde la condición lógica es verdadera o $$PRUNE para "eliminar" el documento donde la condición era falsa.

Esta operación es similar a tener una canalización de $project que selecciona los campos de la colección y crea un nuevo campo que contiene el resultado de la consulta de condición lógica y luego una $match posterior, excepto que $redact usa una sola etapa de canalización que es más eficiente.

En cuanto a la condición lógica, hay operadores de agregación de cadenas que puede usar el operador $strLenCP para verificar la longitud de la cadena. Si la longitud es $gt un valor especificado, entonces esta es una coincidencia real y el documento se "mantiene". De lo contrario, se "poda" y se descarta.

Considere ejecutar la siguiente operación agregada que demuestra el concepto anterior:

db.usercollection.aggregate([ { "$match": { "name": { "$exists": true } } }, { "$redact": { "$cond": [ { "$gt": [ { "$strLenCP": "$name" }, 40] }, "$$KEEP", "$$PRUNE" ] } }, { "$limit": 2 } ])

Si usa $where , intente su consulta sin los corchetes:

db.usercollection.find({$where: "this.name.length > 40"}).limit(2);

Una mejor consulta sería verificar la existencia del campo y luego verificar la longitud:

db.usercollection.find({name: {$type: 2}, $where: "this.name.length > 40"}).limit(2);

o:

db.usercollection.find({name: {$exists: true}, $where: "this.name.length > 40"}).limit(2);

MongoDB evalúa las operaciones de consulta que no son $where antes $where expresiones $where y las declaraciones de consulta non- $where pueden usar un índice. Un rendimiento mucho mejor es almacenar la longitud de la cadena como otro campo y luego puede indexarla o buscarla; aplicar $where será mucho más lento en comparación con eso. Se recomienda utilizar expresiones de JavaScript y el operador $where como último recurso cuando no puede estructurar los datos de otra manera, o cuando se trata de un pequeño subconjunto de datos.

Un enfoque diferente y más rápido que evita el uso de $where operator es el operador $regex . Considere el siguiente patrón que busca

db.usercollection.find({"name": {"$type": 2, "$regex": /^.{41,}$/}}).limit(2);

Nota - De los docs :

Si existe un índice para el campo, MongoDB compara la expresión regular con los valores del índice, que puede ser más rápido que un análisis de recopilación. Se puede lograr una mayor optimización si la expresión regular es una "expresión de prefijo", lo que significa que todas las coincidencias potenciales comienzan con la misma cadena. Esto permite que MongoDB construya un "rango" a partir de ese prefijo y solo coincida con los valores del índice que se encuentran dentro de ese rango.

Una expresión regular es una "expresión de prefijo" si comienza con un símbolo de intercalación (^) o un ancla izquierda (/A) , seguida de una cadena de símbolos simples. Por ejemplo, la expresión regular /^abc.*/ se optimizará haciendo coincidir solo los valores del índice que comienzan con abc .

Además, aunque /^a/, /^a.*/, y /^a.*$/ coinciden con cadenas equivalentes, tienen características de rendimiento diferentes. Todas estas expresiones usan un índice si existe un índice apropiado; sin embargo, /^a.*/ y /^a.*$/ son más lentos. /^a/ puede detener el escaneo después de hacer coincidir el prefijo.