Consulta de documentos donde el tamaño de la matriz es mayor que 1

Tengo una colección MongoDB con documentos en el siguiente formato:

{ "_id" : ObjectId("4e8ae86d08101908e1000001"), "name" : ["Name"], "zipcode" : ["2223"] } { "_id" : ObjectId("4e8ae86d08101908e1000002"), "name" : ["Another ", "Name"], "zipcode" : ["2224"] } 

Actualmente puedo obtener documentos que coincidan con un tamaño de matriz específico:

 db.accommodations.find({ name : { $size : 2 }}) 

Esto devuelve correctamente los documentos con 2 elementos en la matriz de name . Sin embargo, no puedo hacer un comando $gt para devolver todos los documentos donde el campo de name tiene un tamaño de matriz superior a 2:

 db.accommodations.find({ name : { $size: { $gt : 1 } }}) 

¿Cómo puedo seleccionar todos los documentos con una matriz de name de un tamaño mayor que uno (preferiblemente sin tener que modificar la estructura de datos actual)?

Actualizar:

Para mongodb versiones 2.2+ manera más eficiente de hacer esto descrito por @JohnnyHK en otra respuesta .


1.Using $ donde

 db.accommodations.find( { $where: "this.name.length > 1" } ); 

Pero…

Javascript se ejecuta más lentamente que los operadores nativos enumerados en esta página, pero es muy flexible. Consulte la página de procesamiento del lado del servidor para obtener más información.

2. Cree un campo adicional NamesArrayLength , actualícelo con la longitud de la matriz de nombres y luego utilícelo en las consultas:

 db.accommodations.find({"NamesArrayLength": {$gt: 1} }); 

Será una mejor solución y funcionará mucho más rápido (puede crear un índice sobre ella).

Hay una forma más eficiente de hacerlo en MongoDB 2.2+ ahora que puede usar índices de matriz numérica en claves de objeto de consulta.

 // Find all docs that have at least a second name array element. db.accommodations.find({'name.1': {$exists: true}}) 

Creo que esta es la consulta más rápida que responde a su pregunta, porque no usa una cláusula interpretada $where :

 {$nor: [ {name: {$exists: false}}, {name: {$size: 0}}, {name: {$size: 1}} ]} 

Significa “todos los documentos, excepto los que no tienen un nombre (ya sea inexistente o vacío) o con un solo nombre”.

Prueba:

 > db.test.save({}) > db.test.save({name: []}) > db.test.save({name: ['George']}) > db.test.save({name: ['George', 'Raymond']}) > db.test.save({name: ['George', 'Raymond', 'Richard']}) > db.test.save({name: ['George', 'Raymond', 'Richard', 'Martin']}) > db.test.find({$nor: [{name: {$exists: false}}, {name: {$size: 0}}, {name: {$size: 1}}]}) { "_id" : ObjectId("511907e3fb13145a3d2e225b"), "name" : [ "George", "Raymond" ] } { "_id" : ObjectId("511907e3fb13145a3d2e225c"), "name" : [ "George", "Raymond", "Richard" ] } { "_id" : ObjectId("511907e3fb13145a3d2e225d"), "name" : [ "George", "Raymond", "Richard", "Martin" ] } > 

También puedes usar agregado:

 db.accommodations.aggregate( [ {$project: {_id:1, name:1, zipcode:1, size_of_name: {$size: "$name"} } }, {$match: {"size_of_name": {$gt: 1}}} ]) 

// agrega “size_of_name” al documento de tránsito y lo usa para filtrar el tamaño del nombre

Ninguno de los anteriores funcionó para mí. Este lo hizo, así que lo estoy compartiendo:

 db.collection.find( {arrayName : {$exists:true}, $where:'this.arrayName.length>1'} ) 

Intenta hacer algo como esto:

 db.getCollection('collectionName').find({'ArrayName.1': {$exists: true}}) 

1 es el número, si desea obtener un registro mayor que 50, haga ArrayName.50 Gracias.

 db.accommodations.find({"name":{"$exists":true, "$ne":[], "$not":{"$size":1}}}) 

Encontré esta solución para encontrar elementos con un campo de matriz mayor que cierta longitud

 db.allusers.aggregate([ {$match:{username:{$exists:true}}}, {$project: { count: { $size:"$locations.lat" }}}, {$match:{count:{$gt:20}}} ]) 

El primer agregado de $ coincidencias usa un argumento que es verdadero para todos los documentos. Si está en blanco, me gustaría obtener

 "errmsg" : "exception: The argument to $size must be an Array, but was of type: EOO" 

Puede usar $ expr (operador de versión de 3.6 mongo) para usar las funciones de agregación en la consulta normal.

Comparar query operators versus aggregation comparison operators .

 db.accommodations.find({$expr:{$gt:[{$size:"$name"}, 1]}}) 

Aunque todo lo anterior responde a todo, lo que originalmente intentaste hacer fue la forma correcta, sin embargo, solo tienes la syntax al revés (cambia “$ size” y “$ gt”).

Correcto:

 db.collection.find({items: {$gt: {$size: 1}}}) 

Incorrecto:

 db.collection.find({items: {$size: {$gt: 1}}})