diff --git a/src/common/query.ts b/src/common/query.ts
index 70a46d5b749af87c11468de0bc53e47cea137b67..e56ff85b9bbcb67cdd2abf0b89c710fbc6bf4b73 100644
--- a/src/common/query.ts
+++ b/src/common/query.ts
@@ -18,8 +18,11 @@
  * along with blend.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+import { Metric } from "../core/metric";
+import { Dimension } from "../core/dimension";
+
 export interface Query {
-    public metrics: string[];
-    public dimensions: string[];
+    public metrics: Metric[];
+    public dimensions: Dimension[];
 
 }
diff --git a/src/core/engine.spec.ts b/src/core/engine.spec.ts
index e59087d68e28acba644f3363a99d7615e274a0ee..2b9d24b6a0891c1705b34c2a77590d5d284b3f19 100644
--- a/src/core/engine.spec.ts
+++ b/src/core/engine.spec.ts
@@ -24,8 +24,6 @@ import { Engine } from "./engine";
 import { Metric } from "./metric";
 import { Dimension } from "./dimension";
 import { View } from "./view";
-import { ViewOptions } from "./view";
-import { Query } from "../common/query";
 import { AggregationType } from "../common/types";
 
 describe("engine class", () => {
@@ -41,17 +39,19 @@ describe("engine class", () => {
     const met8 = new Metric({ name: "met:8", aggregation: AggregationType.COUNT });
     const met9 = new Metric({ name: "met:9", aggregation: AggregationType.SUM });
     const met10 = new Metric({ name: "met:10", aggregation: AggregationType.COUNT });
+    const met11 = new Metric({ name: "met:11", aggregation: AggregationType.COUNT });
 
-    const dim1 = new Dimension({ name: "dim:0" });
-    const dim2 = new Dimension({ name: "dim:1" });
-    const dim3 = new Dimension({ name: "dim:2" });
-    const dim4 = new Dimension({ name: "dim:3" });
-    const dim5 = new Dimension({ name: "dim:4" });
-    const dim6 = new Dimension({ name: "dim:5" });
-    const dim7 = new Dimension({ name: "dim:6" });
-    const dim8 = new Dimension({ name: "dim:7" });
-    const dim9 = new Dimension({ name: "dim:8" });
-    const dim10 = new Dimension({ name: "dim:9" });
+    const dim1 = new Dimension({ name: "dim:1" });
+    const dim2 = new Dimension({ name: "dim:2" });
+    const dim3 = new Dimension({ name: "dim:3" });
+    const dim4 = new Dimension({ name: "dim:4" });
+    const dim5 = new Dimension({ name: "dim:5" });
+    const dim6 = new Dimension({ name: "dim:6" });
+    const dim7 = new Dimension({ name: "dim:7" });
+    const dim8 = new Dimension({ name: "dim:8" });
+    const dim9 = new Dimension({ name: "dim:9" });
+    const dim10 = new Dimension({ name: "dim:10" });
+    const dim11 = new Dimension({ name: "dim:11" });
 
     engine.addMetric(met1);
     engine.addMetric(met2);
@@ -102,7 +102,13 @@ describe("engine class", () => {
         childViews: [views[7], views[8], views[9]]
     }));
 
+    views.forEach((view) => engine.addView(view));
+
     it("should be create a fill that cover the query and has 4 children", () => {
+        let query = {
+            metrics : [met1, met2, met3, met4, met5, met6, met7, met8, met9, met10]
+            , dimensions : [dim1, dim2, dim3, dim4, dim5, dim6, dim7, dim8, dim9, dim10]
+        };
         let optimalView = engine.query(query);
         expect(optimalView).to.be.an("object");
         expect(optimalView).to.have.property("metrics");
@@ -114,11 +120,11 @@ describe("engine class", () => {
         expect(optimalView.metrics.length === 10);
         expect(optimalView.dimensions.length === 10);
         expect(optimalView.childViews.length === 4);
-        let metAux: number[] = optimalView.metrics.sort().map((item: string) => {
-            return Number(item.split(":")[1]);
+        let metAux: number[] = optimalView.metrics.sort().map((met: Metric) => {
+            return Number(met.name.split(":")[1]);
         });
-        let dimAux: number[] = optimalView.dimensions.sort().map((item: string) => {
-            return Number(item.split(":")[1]);
+        let dimAux: number[] = optimalView.dimensions.sort().map((dim: Dimension) => {
+            return Number(dim.name.split(":")[1]);
         });
         for (let i: number = 1; i <= 10; ++i) {
             expect(dimAux[i] === i);
@@ -128,7 +134,7 @@ describe("engine class", () => {
     it("should throw an exception, query with non-existent metric", () => {
         let error: boolean = false;
         try {
-            engine.query({metrics: ["met:11"], dimensions: ["dim:1"]});
+            engine.query({metrics: [met11], dimensions: [dim1]});
         }
         catch (e){
             error = true;
@@ -141,7 +147,7 @@ describe("engine class", () => {
     it("should throw an exception, query with non-existent dimension", () => {
         let error: boolean = false;
         try {
-            engine.query({metrics: ["met:1"], dimensions: ["dim:11"]});
+            engine.query({metrics: [met1], dimensions: [dim11]});
         }
         catch (e){
             error = true;
diff --git a/src/core/engine.ts b/src/core/engine.ts
index a7b3bf06f1dc1072e5fd90967af12b49665359aa..e810f570b64e1cf022961217d766c6d460dbad1e 100644
--- a/src/core/engine.ts
+++ b/src/core/engine.ts
@@ -21,7 +21,6 @@
 import { Dimension } from "./dimension";
 import { Metric } from "./metric";
 import { View } from "./view";
-import { AggregationType } from "../common/types";
 import { Query } from "../common/query";
 
 export class Engine {
@@ -49,7 +48,7 @@ export class Engine {
         let result = this.metrics.find(metric => metric.name === name);
 
         if (!result) {
-            throw new Error('The metric named ' + name + ' was not found');
+            throw new Error("The metric named " + name + " was not found");
         }
 
         return result;
@@ -64,7 +63,7 @@ export class Engine {
         let result = this.dimensions.find(dimension => dimension.name === name);
 
         if (!result) {
-            throw new Error('The dimension named ' + name + ' was not found');
+            throw new Error("The dimension named " + name + " was not found");
         }
 
         return result;
@@ -75,7 +74,9 @@ export class Engine {
     }
 
     private selectOptimalView (q: Query) {
-        let objective = q.metrics.concat(q.dimensions);
+        let metricsName = q.metrics.map((met) => met.name);
+        let dimensionsName = q.dimensions.map((dim) => dim.name);
+        let objective = metricsName.concat(dimensionsName);
         let optimalViews: View[] = [];
         let activeViews = this.getViews();
 
@@ -87,7 +88,9 @@ export class Engine {
             // remove views from the activeViews if they don't intersect
             // with the objective
             activeViews = activeViews.filter((view: View) => {
-                let cover = view.metrics.concat(view.dimensions);
+                metricsName = view.metrics.map((met) => met.name);
+                dimensionsName = view.dimensions.map((dim) => dim.name);
+                let cover = metricsName.concat(dimensionsName);
                 let intersection = cover.filter((item: string) => {
                     return objective.indexOf(item) !== -1;
                 });
@@ -116,12 +119,13 @@ export class Engine {
             // remove metrics and dimensions corvered by the bestView from the
             // objective (i.e. the object is already met for those metrics/dimensions)
             objective = objective.filter((item: string) => {
-                let cover = bestView.dimensions.concat(bestView.metrics);
+                metricsName = bestView.metrics.map((met) => met.name);
+                dimensionsName = bestView.dimensions.map((dim) => dim.name);
+                let cover = dimensionsName.concat(metricsName);
                 return cover.indexOf(item) === -1;
             });
         }
 
-        
         if (optimalViews.length === 1) {
             // if there is a single view that covers the query, we just return it
             return optimalViews.pop();
@@ -130,18 +134,10 @@ export class Engine {
             // if more than one view is necessary to cover the query,
             // we need to compose them into a new singular virtual view
 
-            let map = new Map();
-            optimalViews.forEach((view: View) => {
-                view.aggregationMap.forEach((value: AggregationType, key: string) => {
-                    map.set(key, value);
-                });
-            });
-
             let options = {
                 metrics: q.metrics,
                 dimensions: q.dimensions,
                 materialized: false,
-                aggregationMap: map,
                 childViews: optimalViews
             };