Longitud del valor del campo de cadena en mongoDB

El tipo de datos del campo es Cadena. Me gustaría buscar los datos donde la longitud del carácter del nombre del campo es mayor que 40.

Intenté estas consultas pero devolviendo 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 está trabajando en 2.4.9 pero mi versión es 2.6.5

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 que 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 $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 $project que selecciona los campos en 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, existen operadores de agregación de cadenas que pueden usar el operador $strLenCP para verificar la longitud de la cadena. Si la longitud es $gt un valor especificado, entonces esta es una coincidencia verdadera 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 adjuntos:

 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 de $where expresiones y las sentencias de consulta que no son $where pueden usar un índice. Un rendimiento mucho mejor es almacenar la longitud de la cadena como otro campo y luego puede indexar o buscar en ella; aplicando $where será mucho más lento en comparación con eso. Se recomienda usar expresiones de JavaScript y el operador $where como último recurso cuando no se pueden 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 del operador $where operador $regex . Considere el siguiente patrón que busca

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

Nota – De los documentos :

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 escaneo de colección. La optimización adicional puede ocurrir 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 a MongoDB construir un “rango” a partir de ese prefijo y solo coincide con aquellos valores del índice que caen 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 delimitador izquierdo (\A) , seguido 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, mientras /^a/, /^a.*/, y /^a.*$/ coinciden con cadenas de caracteres, tienen diferentes características de rendimiento. 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.

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 eso. Así que pensé en compartir mi solución con todos ustedes (espero que esto ayude a cualquier persona con un tipo similar de problema).

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

Ejemplo: si necesitamos obtener solo colecciones que tengan una longitud de nombre de niño superior a 10 caracteres.

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

una actualización de Mongo 4.0, se vuelve más fácil y más fluido:

 find({name: { $gt: 40 }}, function(err, posts){ res.render('blog', {posts:posts}); // your code here }); 
    Intereting Posts