Using $ unwind on object properties

3

Is it possible to use $unwind on the properties of an object when making a query with agregation in MongoDB v3?

I need to extract the controls that meet certain conditions in each object of the array of objects in each area code. The question is that the keys in areas may vary. You can have two keys as in the example, but in other cases you can have up to 3 and 4 four keys.

{
   id: 12,
   name: "adsdf",
   areas: {
      clave1: [
         {
            "controles": ["valor1","valor2","valor3"]          
         },
         {
            "controles": ["valor4","valor5","valor6"]          
         }
      ],
      clave2: [
         {
            "controles": ["valor7","valor8","valor9"]          
         },
         {
            "controles": ["valor10","valor11","valor12"]          
         }
      ]
   }
}

A result would be something like this, for example:

{
   id: 12,
   name: "adsdf",
   areas: {
      clave1: [
         {
            "controles": ["valor1","valor3"]          
         },
         {
            "controles": ["valor5"]          
         }
      ],
      clave2: [
         {
            "controles": ["valor9"]          
         },
         {
            "controles": ["valor12"]
         }
      ]
   }
}
    
asked by wchopite 16.12.2015 в 13:14
source

2 answers

1

MongoDB is a system in which there is no predefined schema for the objects in a collection. It is very probable and, in addition highly recommended, that the documents of a particular collection have a similar structure. If it happens that there are documents in the same collection with a different structure, we will have to manage it in the logic of the application.

In your particular case, the "areas" field differs from one document to another, since it contains different fields: key 1, key2 for a document; key 1, key 2, key 3 for another document; etc.

The nature of the field itself leads us to think that it should be of the array type, since it contains a random number of elements and that, moreover, they are of the same type.

On the other hand, and as César Bustíos has commented, the $unwind aggregation framework command only works on arrays.

That said, an approach to solve your problem may consist of conducting a search of the names of the fields contained in the subdocument "areas" using mapReduce and from the results, search the value of those fields by programming. The following example can help you get the names of these fields:

mr = db.mapreduce.mapReduce(
    function() { for (var key in this.areas) {emit(key, null)}},
    function(key, stuff) {return null;},
    { out:"my_collection" + "_keys" }
)

db[mr.result].distinct("_id")
    
answered by 16.12.2015 / 22:30
source
2

The documentation of $unwind is very clear what you can achieve. Using that same example, if you have a inventario collection:

{ "_id" : 1, "item" : "ABC1", sizes: [ "S", "M", "L"] }

Using $unwind you can get a document for each element of the array sizes :

db.inventario.aggregate( [ { $unwind : "$sizes" } ] )

Will throw you as a result:

{ "_id" : 1, "item" : "ABC1", "sizes" : "S" }
{ "_id" : 1, "item" : "ABC1", "sizes" : "M" }
{ "_id" : 1, "item" : "ABC1", "sizes" : "L" }

It's like doing an "explode" to the array sizes .

    
answered by 16.12.2015 в 15:39