Consulta de documentos donde el tamaño del array 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 coinciden con un tamaño de matriz específico:
db.accommodations.find({ name : { $size : 2 }})
Esto devuelve correctamente los documentos con 2 elementos en el array name
. Sin embargo, no puedo hacer un comando $gt
para devolver todos los documentos donde el campo name
tiene un tamaño de matriz mayor que 2:
db.accommodations.find({ name : { $size: { $gt : 1 } }})
¿Cómo puedo seleccionar todos los documentos con una matriz name
de un tamaño mayor que uno (preferiblemente sin tener que modificar la estructura de datos actual)?
10 answers
Actualización:
Para versiones mongodb 2.2+ una forma más eficiente de hacer esto descrita por @JohnnyHK en otra respuesta .
1.Usando where donde
db.accommodations.find( { $where: "this.name.length > 1" } );
Pero...
Javascript se ejecuta más lentamente que los operadores nativos listados en esta página, pero es muy flexible. Consulte la página de procesamiento del lado del servidor para más información.
2.Crear extra campo NamesArrayLength
, actualizarlo con la longitud de la matriz de nombres y luego usar en consultas:
db.accommodations.find({"NamesArrayLength": {$gt: 1} });
Será una mejor solución, y funcionará mucho más rápido (puede crear un índice en él).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:36
Hay una forma más eficiente de hacer esto 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}})
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-12 21:18:18
Creo que esta es la consulta más rápida que responde a su pregunta, porque no utiliza una cláusula interpretada $where
:
{$nor: [
{name: {$exists: false}},
{name: {$size: 0}},
{name: {$size: 1}}
]}
Significa "todos los documentos excepto aquellos sin un nombre (ya sea un array 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" ] }
>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-11 15:08:03
También puedes usar aggregate:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-23 19:00:06
Nada de lo anterior funcionó para mí. Este lo hizo así que lo estoy compartiendo:
db.collection.find( {arrayName : {$exists:true}, $where:'this.arrayName.length>1'} )
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-14 01:06:04
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.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-19 06:37:16
db.accommodations.find({"name":{"$exists":true, "$ne":[], "$not":{"$size":1}}})
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-22 13:54:14
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 match match usa un argumento que es verdadero para todos los documentos. Si estuviera en blanco, obtendría
"errmsg" : "exception: The argument to $size must be an Array, but was of type: EOO"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-06 01:46:59
Puede usar exp expr (3.6 mongo version operator ) para usar funciones de agregación en consultas regulares.
Comparar query operators
vs aggregation comparison operators
.
db.accommodations.find({$expr:{$gt:[{$size:"$name"}, 1]}})
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-23 21:13:50
Aunque todas las respuestas anteriores funcionan, lo que originalmente intentó hacer fue de la manera correcta, sin embargo, solo tiene la sintaxis al revés (cambiar "size size" y "gt gt")..
Correcto:
db.collection.find({items: {$gt: {$size: 1}}})
Incorrecto:
db.collection.find({items: {$size: {$gt: 1}}})
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-10 01:15:48