I'm trying to find all documents that tipo=CD
and canciones does not contains subdocuments that has title=Pajaritos
and cancion=2
This is what i like to achieve in canciones
field:
not (title=Pajaritos and cancion=2)
I have the following collection:
{
"tipo": "CD",
"Artista":"Los piratas",
"Titulo": "Recuerdos",
"canciones": [
{
"cancion":1,
"titulo":"Adios mi barco",
"longitud": "3:20"
},
{
"cancion":2,
"titulo":"Pajaritos",
"longitud": "4:15"
}
]
},
{
"tipo": "CD",
"Artista":"Los piratas",
"Titulo": "Recuerdos",
"canciones": [
{
"cancion":1,
"titulo":"Adios mi barco",
"longitud": "3:20"
},
{
"cancion":3,
"titulo":"Pajaritos",
"longitud": "4:15"
}
]
},
{
"tipo": "CD",
"Artista":"Los piratas",
"Titulo": "Recuerdos",
"canciones": [
{
"cancion":1,
"titulo":"Adios mi barco",
"longitud": "3:20"
},
{
"cancion":3,
"titulo":"Pajaritos",
"longitud": "4:15"
},
{
"cancion":4,
"titulo":"Pajaritos4",
"longitud": "44:15"
}
}
My query
db.media.find({"tipo" : "CD" ,"canciones" : { "$ne" : {"$elemMatch" : {"titulo" : "Pajaritos", "cancion" : 2}}}})
My undesired results
{ "_id" : ObjectId("550f0a1c009ed3a1c9bbcdc1"), "tipo" : "CD", "Artista" : "Los piratas", "Titulo" : "Recuerdos", "canciones" : [ { "cancion" : 1, "titulo" : "Adios mi barco", "longitud" : "3:20" }, { "cancion" : 2, "titulo" : "Pajaritos", "longitud" : "4:15" } ] }
{ "_id" : ObjectId("550f0a1c009ed3a1c9bbcdc2"), "tipo" : "CD", "Artista" : "Los piratas", "Titulo" : "Recuerdos", "canciones" : [ { "cancion" : 1, "titulo" : "Adios mi barco", "longitud" : "3:20" }, { "cancion" : 3, "titulo" : "Pajaritos", "longitud" : "4:15" } ] }
{ "_id" : ObjectId("550f0a1c009ed3a1c9bbcdc3"), "tipo" : "CD", "Artista" : "Los piratas", "Titulo" : "Recuerdos", "canciones" : [ { "cancion" : 1, "titulo" : "Adios mi barco", "longitud" : "3:20" }, { "cancion" : 3, "titulo" : "Pajaritos", "longitud" : "4:15" }, { "cancion" : 4, "titulo" : "Pajaritos4", "longitud" : "44:15" } ] }
As you can see, the results contains "titulo" : "Pajaritos"
which is trying to avoid.
Trying with $not
operator instead of $ne
{ "_id" : ObjectId("550f173fc357b7a4e7a46e10"), "tipo" : "CD", "Artista" : "Los piratas", "Titulo" : "Recuerdos", "canciones" : [ { "cancion" : 1, "titulo" : "Adios mi barco", "longitud" : "3:20" }, { "cancion" : 3, "titulo" : "Pajaritos", "longitud" : "4:15" } ] }
{ "_id" : ObjectId("550f173fc357b7a4e7a46e11"), "tipo" : "CD", "Artista" : "Los piratas", "Titulo" : "Recuerdos", "canciones" : [ { "cancion" : 1, "titulo" : "Adios mi barco", "longitud" : "3:20" }, { "cancion" : 3, "titulo" : "Pajaritos", "longitud" : "4:15" }, { "cancion" : 4, "titulo" : "Pajaritos4", "longitud" : "44:15" } ] }
$all operator retrieves all the documents which contains the subset of the values we pass. The subset might be in any order. $in operator retrieves all the documents which contains the either of the values we pass. db.
Definition. The $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria.
To search the array of object in MongoDB, you can use $elemMatch operator. This operator allows us to search for more than one component from an array object.
Use $match With $all to Find Matching Documents in an Array in MongoDB. The $all is equivalent to the $and operator. This code retrieves all those documents where the courses array contains all the specified elements for the $all operator. The resulting documents must contain Java and Python elements.
In order to get the expected results, I would use the $not operator instead of the $ne operator. The $not operator would pretty match negate $elemMatch and give you the expected results. Your query shall therefore be:
db.media.find({
"tipo": "CD",
"canciones": {
"$not": {
"$elemMatch": {
"titulo": "Pajaritos",
"cancion": 2
}
}
}
})
I hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With