diff --git a/src/adapter/postgres.spec.ts b/src/adapter/postgres.spec.ts
index cae97a84b9676aef05865d63c8a43ab783a279cf..18583960504ee4918d1b68060a6b78c77c82a870 100644
--- a/src/adapter/postgres.spec.ts
+++ b/src/adapter/postgres.spec.ts
@@ -169,4 +169,76 @@ describe("postgres adapter", () => {
             done();
         });
     });
+
+    it("should get data from view when a single clause exists", (done) => {
+        let view = adapterScenario.clauseView;
+        adapter.getDataFromView(view, (err, result) => {
+            expect(err).to.be.a("null");
+            expect(result).to.be.an("array");
+            expect(result).to.have.length(1);
+            expect(result[0]).to.be.an("object");
+            let keys: string[] = [];
+            keys = keys.concat(view.metrics.map((item) => item.name));
+            keys = keys.concat(view.dimensions.map((item) => item.name));
+            result.forEach((row) => {
+                expect(row).to.be.an("object");
+                expect(row).to.have.all.keys(keys);
+            });
+
+            expect(parseInt(result[0]["met:0"], 10)).to.be.equal(1);
+            expect(parseInt(result[0]["met:1"], 10)).to.be.equal(1);
+            expect(parseInt(result[0]["met:2"], 10)).to.be.equal(1);
+            expect(result[0]["dim:0"].getDate()).to.be.equal(1);
+            done();
+        });
+    });
+
+    it("should get data from view with single clause,  with more than on filter", (done) => {
+        let view = adapterScenario.multiFilterView;
+        adapter.getDataFromView(view, (err, result) => {
+            expect(err).to.be.a("null");
+            expect(result).to.be.an("array");
+            expect(result).to.have.length(2);
+            expect(result[0]).to.be.an("object");
+            let keys: string[] = [];
+            keys = keys.concat(view.metrics.map((item) => item.name));
+            keys = keys.concat(view.dimensions.map((item) => item.name));
+            result.forEach((row) => {
+                expect(row).to.be.an("object");
+                expect(row).to.have.all.keys(keys);
+            });
+
+            done();
+        });
+    });
+
+    it("should get data from view with multiple clauses", (done) => {
+        let view = adapterScenario.multiClauseView;
+        adapter.getDataFromView(view, (err, result) => {
+            expect(err).to.be.a("null");
+            expect(result).to.be.an("array");
+            expect(result).to.have.length(0);
+
+            done();
+        });
+    });
+
+    it("should get data from view with a clause with not equal operator", (done) => {
+        let view = adapterScenario.notEqualView;
+        adapter.getDataFromView(view, (err, result) => {
+            expect(err).to.be.a("null");
+            expect(result).to.be.an("array");
+            expect(result).to.have.length(4);
+            expect(result[0]).to.be.an("object");
+            let keys: string[] = [];
+            keys = keys.concat(view.metrics.map((item) => item.name));
+            keys = keys.concat(view.dimensions.map((item) => item.name));
+            result.forEach((row) => {
+                expect(row).to.be.an("object");
+                expect(row).to.have.all.keys(keys);
+            });
+
+            done();
+        });
+    });
 });
diff --git a/src/adapter/postgres.ts b/src/adapter/postgres.ts
index d12c6894a930d0408e98892d09c93a43ce7080fd..df8623e22312a8740a489fb76e6158ace1c86792 100644
--- a/src/adapter/postgres.ts
+++ b/src/adapter/postgres.ts
@@ -21,6 +21,8 @@
 import { Adapter } from "../core/adapter";
 import { Metric } from "../core/metric";
 import { Dimension } from "../core/dimension";
+import { Clause } from "../core/clause";
+import { Filter, FilterOperator } from "../core/filter";
 import { AggregationType, RelationType } from "../common/types";
 import { View } from "../core/view";
 import { Pool, PoolConfig } from "pg";
@@ -38,9 +40,6 @@ export class PostgresAdapter extends Adapter {
         this.pool = new Pool(config);
     }
     public getDataFromView(view: View, cb: (error: Error, result?: any[]) => void): void {
-        // buildQueryFromView does not put the final ;, it need to be put apart
-        // let query =  this.buildQueryFromView(view, view.metrics, view.dimensions) + ";\n";
-
         const materialized = this.searchMaterializedViews(view).sort((a, b) => {
             return (a.id < b.id) ? -1 : 1;
         });
@@ -70,54 +69,6 @@ export class PostgresAdapter extends Adapter {
         return false;
     }
 
-    private getAggregateFunction(aggrType: AggregationType, origin: boolean): string {
-        switch (aggrType) {
-            case AggregationType.SUM:
-                return "SUM";
-            case AggregationType.AVG:
-                return "AVG";
-            case AggregationType.COUNT:
-                return (origin) ? "COUNT" : "SUM";
-            default:
-                return  "";
-        }
-
-    }
-
-    private translateRelation(relation: RelationType, arg: string): string {
-        switch (relation) {
-            case RelationType.DAY:
-                return this.applyRelation("EXTRACT", ["DAY FROM "], [arg]);
-            case RelationType.MONTH:
-                return this.applyRelation("EXTRACT", ["MONTH FROM "], [arg]);
-            case RelationType.YEAR:
-                return this.applyRelation("EXTRACT", ["YEAR FROM "], [arg]);
-            case RelationType.DAYOFWEEK:
-                return this.applyRelation("EXTRACT", ["DOW FROM "], [arg]);
-            default:
-                return "";
-        }
-
-    }
-
-    private applyRelation(name: string, args: string[], values: string[]): string {
-        /*
-            This adapter uses the concept of functions in Postgres to
-            implement BLENDB sub-dimention relations, this functions
-            applys the transformation to build the call of a Postgres
-            funtion. Note that this function can be native from postgres,
-            like EXTRACT, or even implemented on the database.
-            This function is short and only used in the translateRelation
-            method however is a bit complex and is possible to be used
-            several times, because of that is puted appart to make easyer update
-            and avoid problems
-            Example
-            applyRelation ("EXTRACT", "["DAY FROM"]", ["view_0.date"])
-            output: EXTRACT(DAY FROM view_0.date)
-        */
-        return name + "(" + args.map((item, idx) => item + values[idx]).join(",") + ")";
-    }
-
     private searchMaterializedViews(view: View): View[] {
         let r: View[] = [];
         if (view.materialized) {
@@ -137,9 +88,11 @@ export class PostgresAdapter extends Adapter {
     private buildQuery(target: View, views: View[]) {
         const metrics = target.metrics;
         const dimensions = target.dimensions;
+        const clauses = target.clauses;
 
         let dimMap: {[key: string]: DimInfo} = {};
         let metMap: {[key: string]: View[]} = {};
+        let nameMap: {[key: string]: View} = {};
 
         for (let i = 0; i < views.length; ++i) {
             const mets = views[i].metrics;
@@ -147,6 +100,7 @@ export class PostgresAdapter extends Adapter {
             for (let j = 0; j < mets.length; ++j) {
                 if (!metMap[mets[j].name])  {
                     metMap[mets[j].name] = [views[i]];
+                    nameMap[mets[j].name] = views[i];
                 }
 
                 else {
@@ -160,6 +114,7 @@ export class PostgresAdapter extends Adapter {
                         dim: dims[j],
                         views: [views[i]]
                     };
+                    nameMap[dims[j].name] = views[i];
                 }
 
                 else {
@@ -168,24 +123,23 @@ export class PostgresAdapter extends Adapter {
             }
         }
 
+        // Projection
         const strMetrics = metrics.map((metric) => {
-            const view = metMap[metric.name][0];
+            const view = nameMap[metric.name];
             let func = this.getAggregateFunction(metric.aggregation, view.origin);
             let quotedName = "\"" + metric.name + "\"";
-            let extMetric = func + "(view_" + view.id + "." + quotedName + ")";
+            let extMetric = func + "(" + this.buildColumn(metric, view.id) + ")";
             return extMetric + " AS " + quotedName;
         });
 
         const parsedDimensions = dimensions.map((dimension) => {
             let dim = dimension;
-            while (!dimMap[dim.name]) {
-                // Checar exeção
+            while (!nameMap[dim.name]) {
                 dim = dim.parent;
             }
-            const view = dimMap[dim.name].views[0];
-            const quotedDim = "\"" + dim.name + "\"";
+            const view = nameMap[dim.name];
             const quotedName = "\"" + dimension.name + "\"";
-            let extDimension = "view_" + view.id + "." + quotedDim;
+            let extDimension = this.buildColumn(dim, view.id);
             let aux = dimension;
             while (aux.name !== dim.name) {
                 extDimension = this.translateRelation(aux.relation, extDimension);
@@ -198,7 +152,8 @@ export class PostgresAdapter extends Adapter {
         const grouped = parsedDimensions.map((item) => item.noalias);
         const elements = strMetrics.concat(strDimensions);
 
-        let joins = [];
+        // Joins
+        let conds: string[] = [];
         for (let i in dimMap) {
             let remainViews = dimMap[i].views.slice();
             let dim = dimMap[i].dim;
@@ -207,15 +162,30 @@ export class PostgresAdapter extends Adapter {
                 while (remainViews.length > 0) {
                     const id = remainViews.shift().id;
                     const rightSide = this.buildColumn(dim, id);
-                    joins.push(leftSide + " = " + rightSide);
+                    conds.push(leftSide + " = " + rightSide);
                 }
             }
 
         }
 
+        // Selection
+        let covered: Clause[] = [];
+        for (let i = 0; i < views.length; ++i) {
+            // Get the clauses that children already cover
+            covered = covered.concat(views[i].clauses);
+        }
+
+        const toCover = clauses.filter((item) => !covered.some ((clause) => {
+            return clause.id === item.id;
+        }));
+
+        toCover.forEach((item) => conds.push("(" + this.translateClause(item, nameMap) + ")"));
+
+        // Assembly
+
         const projection = "SELECT " + elements.join(",");
         const source = " FROM " + views.map((view) => "view_" + view.id).join(",");
-        const selection = (joins.length > 0) ? " WHERE " + joins.join(" AND ") : "";
+        const selection = (conds.length > 0) ? " WHERE " + conds.join(" AND ") : "";
         let grouping = "";
         if (grouped.length > 0) {
             grouping = " GROUP BY " + grouped.join(",");
@@ -225,8 +195,93 @@ export class PostgresAdapter extends Adapter {
 
     }
 
+    private getAggregateFunction(aggrType: AggregationType, origin: boolean): string {
+        switch (aggrType) {
+            case AggregationType.SUM:
+                return "SUM";
+            case AggregationType.AVG:
+                return "AVG";
+            case AggregationType.COUNT:
+                return (origin) ? "COUNT" : "SUM";
+            default:
+                return  "";
+        }
+
+    }
+
+    private translateRelation(relation: RelationType, arg: string): string {
+        switch (relation) {
+            case RelationType.DAY:
+                return this.applyRelation("EXTRACT", ["DAY FROM "], [arg]);
+            case RelationType.MONTH:
+                return this.applyRelation("EXTRACT", ["MONTH FROM "], [arg]);
+            case RelationType.YEAR:
+                return this.applyRelation("EXTRACT", ["YEAR FROM "], [arg]);
+            case RelationType.DAYOFWEEK:
+                return this.applyRelation("EXTRACT", ["DOW FROM "], [arg]);
+            default:
+                return "";
+        }
+
+    }
+
+    private applyRelation(name: string, args: string[], values: string[]): string {
+        /*
+            This adapter uses the concept of functions in Postgres to
+            implement BLENDB sub-dimention relations, this functions
+            applys the transformation to build the call of a Postgres
+            funtion. Note that this function can be native from postgres,
+            like EXTRACT, or even implemented on the database.
+            This function is short and only used in the translateRelation
+            method however is a bit complex and is possible to be used
+            several times, because of that is puted appart to make easyer update
+            and avoid problems
+            Example
+            applyRelation ("EXTRACT", "["DAY FROM"]", ["view_0.date"])
+            output: EXTRACT(DAY FROM view_0.date)
+        */
+        return name + "(" + args.map((item, idx) => item + values[idx]).join(",") + ")";
+    }
+
     private buildColumn (item: Metric|Dimension, id: string): string {
         const quotedName = "\"" + item.name + "\"";
         return "view_" + id + "." + quotedName;
     }
+
+    private translateClause(clause: Clause, map: {[key: string]: View}): string {
+        let r = clause.filters.map((item) => this.translateFilter(item, map));
+        return r.join(" OR ");
+    }
+
+    private translateFilter(filter: Filter, map: {[key: string]: View}): string {
+        const viewId = map[filter.target.name].id;
+        const leftSide = this.buildColumn(filter.target, viewId);
+        const op = this.translateOperator(filter.operator);
+        const dataType = this.translateDataType(filter.target.dataType);
+        const quotedValue = "'" + filter.value + "'";
+        return leftSide + op + quotedValue + dataType;
+    }
+
+    private translateOperator(op: FilterOperator): string {
+        switch (op) {
+            case FilterOperator.EQUAL:
+                return " = ";
+            case FilterOperator.NOTEQUAL:
+                return " != ";
+            default:
+                return  "";
+        }
+
+    }
+
+    private translateDataType(dt: string ): string {
+        switch (dt) {
+            case "date":
+                return "::DATE";
+            case "integer":
+                return "::INTEGER";
+            default:
+                return "";
+        }
+    }
 }
diff --git a/src/api/controllers/data.spec.ts b/src/api/controllers/data.spec.ts
index c9aec893fdf9b42957fc446c023aad191449a062..4e1ca99c6b2403f422812508dfaa3e22d695f70b 100644
--- a/src/api/controllers/data.spec.ts
+++ b/src/api/controllers/data.spec.ts
@@ -28,6 +28,7 @@ import { Query } from "../../common/query";
 interface StrQuery {
     metrics: string;
     dimensions: string;
+    filters?: string;
 }
 
 function parseQuery(obj: Query): StrQuery {
@@ -94,4 +95,79 @@ describe("API data controller", () => {
             .end(done);
     });
 
+    it("should respond 200 and get some data, using a single filter", (done) => {
+        // Clause does not come to scenario besause is a lot of work for
+        // only a single test
+        let query = parseQuery(tests.clausal);
+        query.filters = "dim:7==1";
+        request(server)
+            .get("/v1/data")
+            .query(query)
+            .expect(200)
+            .expect((res: any) => {
+                let result = res.body;
+                expect(result).to.be.an("array");
+                expect(result).to.have.length(1);
+                expect(result[0]).to.be.an("object");
+                let keys: string[] = [];
+                keys = keys.concat(tests.clausal.metrics.map((item) => item.name));
+                keys = keys.concat(tests.clausal.dimensions.map((item) => item.name));
+                result.forEach((row: any) => {
+                    expect(row).to.be.an("object");
+                    expect(row).to.have.all.keys(keys);
+                });
+            })
+            .end(done);
+    });
+
+    it("should respond 200 and get some data, using filters with OR", (done) => {
+        // Clause does not come to scenario besause is a lot of work for
+        // only a single test
+        let query = parseQuery(tests.clausal);
+        query.filters = "dim:7==1,dim:7==2";
+        request(server)
+            .get("/v1/data")
+            .query(query)
+            .expect(200)
+            .expect((res: any) => {
+                let result = res.body;
+                expect(result).to.be.an("array");
+                expect(result).to.have.length(2);
+                expect(result[0]).to.be.an("object");
+                let keys: string[] = [];
+                keys = keys.concat(tests.clausal.metrics.map((item) => item.name));
+                keys = keys.concat(tests.clausal.dimensions.map((item) => item.name));
+                result.forEach((row: any) => {
+                    expect(row).to.be.an("object");
+                    expect(row).to.have.all.keys(keys);
+                });
+            })
+            .end(done);
+    });
+
+    it("should respond 200 and get some data, using filters with AND", (done) => {
+        // Clause does not come to scenario besause is a lot of work for
+        // only a single test
+        let query = parseQuery(tests.clausal);
+        query.filters = "dim:7!=1;dim:0!=2017-01-01";
+        request(server)
+            .get("/v1/data")
+            .query(query)
+            .expect(200)
+            .expect((res: any) => {
+                let result = res.body;
+                expect(result).to.be.an("array");
+                expect(result).to.have.length(4);
+                expect(result[0]).to.be.an("object");
+                let keys: string[] = [];
+                keys = keys.concat(tests.clausal.metrics.map((item) => item.name));
+                keys = keys.concat(tests.clausal.dimensions.map((item) => item.name));
+                result.forEach((row: any) => {
+                    expect(row).to.be.an("object");
+                    expect(row).to.have.all.keys(keys);
+                });
+            })
+            .end(done);
+    });
+
 });
diff --git a/src/api/controllers/data.ts b/src/api/controllers/data.ts
index 285fc91e28e17cf6e50648c27a85bceccdef0f8a..97b55a49cfb90964454cb13076b2368216574db9 100644
--- a/src/api/controllers/data.ts
+++ b/src/api/controllers/data.ts
@@ -26,10 +26,14 @@ export class DataCtrl {
     public static read(req: Request, res: express.Response, next: express.NextFunction) {
         let metrics = req.query.metrics.split(",").filter((item: string) => item !== "");
         let dimensions = req.query.dimensions.split(",").filter((item: string) => item !== "");
+        let clauses = [];
+        if (req.query.filters) {
+            clauses = req.query.filters.split(";").filter((item: string) => item !== "");
+        }
         let view;
 
         try {
-            let query: Query = { metrics: [], dimensions: [] };
+            let query: Query = { metrics: [], dimensions: [], clauses: [] };
             for (let i = 0; i < metrics.length; ++i) {
                 query.metrics.push(req.engine.getMetricByName(metrics[i]));
             }
@@ -37,6 +41,10 @@ export class DataCtrl {
             for (let i = 0; i < dimensions.length; ++i) {
                 query.dimensions.push(req.engine.getDimensionByName(dimensions[i]));
             }
+
+            for (let i = 0; i < clauses.length; ++i) {
+                query.clauses.push(req.engine.parseClause(clauses[i]));
+            }
             view = req.engine.query(query);
         }
         catch (e) {
diff --git a/src/common/query.ts b/src/common/query.ts
index e56ff85b9bbcb67cdd2abf0b89c710fbc6bf4b73..dcbcb1f24cbec0d4ef85b45859facf519f85c4f8 100644
--- a/src/common/query.ts
+++ b/src/common/query.ts
@@ -20,9 +20,10 @@
 
 import { Metric } from "../core/metric";
 import { Dimension } from "../core/dimension";
+import { Clause } from "../core/clause";
 
 export interface Query {
     public metrics: Metric[];
     public dimensions: Dimension[];
-
+    public clauses?: Clause[];
 }
diff --git a/src/core/clause.ts b/src/core/clause.ts
new file mode 100644
index 0000000000000000000000000000000000000000..11a831dc55cc90349305958189d17d79175cecb0
--- /dev/null
+++ b/src/core/clause.ts
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 Centro de Computacao Cientifica e Software Livre
+ * Departamento de Informatica - Universidade Federal do Parana
+ *
+ * This file is part of blend.
+ *
+ * blend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * blend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with blend.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import { Filter } from "./filter";
+import { Hash } from "../util/hash";
+
+export interface ClauseOptions {
+    filters: Filter[];
+}
+
+export class Clause {
+    public readonly id: string;
+    public readonly filters: Filter[];
+
+    constructor (options: ClauseOptions) {
+        this.filters = options.filters;
+        const filtersIds = this.filters.map((item) => item.id);
+        this.id = Hash.sha1(filtersIds.sort());
+    }
+
+}
diff --git a/src/core/engine.spec.ts b/src/core/engine.spec.ts
index cefbf13d104a7db4be78c4939300fefb146fb26f..00ad8be38c2f1bb66950dd2143e295ba5f4ccc39 100644
--- a/src/core/engine.spec.ts
+++ b/src/core/engine.spec.ts
@@ -23,6 +23,7 @@ import { expect } from "chai";
 import { Engine } from "./engine";
 import { Metric } from "./metric";
 import { Dimension } from "./dimension";
+import { FilterOperator } from "./filter";
 import { View } from "./view";
 import { engineScenario } from "../../test/scenario";
 
@@ -182,4 +183,91 @@ describe("engine class", () => {
         }
         expect(error).to.be.true;
     });
+
+    it("should parse a clause, with target as dimension and operator as ==", () => {
+        const strFilter = "dim:0==0";
+        const clause = engine.parseClause(strFilter);
+        expect(clause).to.be.an("object");
+        expect(clause).to.have.property("filters");
+        expect(clause).to.have.property("id");
+        expect(clause.filters).to.be.an("array");
+        expect(clause.filters).to.have.length(1);
+        expect(clause.filters[0]).to.have.property("id");
+        expect(clause.filters[0]).to.have.property("target");
+        expect(clause.filters[0]).to.have.property("value");
+        expect(clause.filters[0]).to.have.property("operator");
+        expect(clause.filters[0].target).to.be.equal(dim[0]);
+        expect(clause.filters[0].value).to.be.equal("0");
+        expect(clause.filters[0].operator).to.be.equal(FilterOperator.EQUAL);
+    });
+    it("should parse a clause, with target as metric and operator as !=", () => {
+        const strFilter = "met:0!=0";
+        const clause = engine.parseClause(strFilter);
+        expect(clause).to.be.an("object");
+        expect(clause).to.have.property("filters");
+        expect(clause).to.have.property("id");
+        expect(clause.filters).to.be.an("array");
+        expect(clause.filters).to.have.length(1);
+        expect(clause.filters[0]).to.have.property("id");
+        expect(clause.filters[0]).to.have.property("target");
+        expect(clause.filters[0]).to.have.property("operator");
+        expect(clause.filters[0]).to.have.property("value");
+        expect(clause.filters[0].target).to.be.equal(met[0]);
+        expect(clause.filters[0].value).to.be.equal("0");
+        expect(clause.filters[0].operator).to.be.equal(FilterOperator.NOTEQUAL);
+    });
+    it("should throw an exception, when a dimension is not found", () => {
+        let error: boolean = false;
+        const strFilter = "dim:-1==0";
+        const exeption = "Filter could not be created: \"dim:-1\" was not found";
+        try {
+            engine.parseClause(strFilter);
+        }
+        catch (e){
+            error = true;
+            expect(e.message).to.be.equal(exeption);
+
+        }
+        expect(error).to.be.true;
+    });
+    it("should throw an exception, when a metric is not found", () => {
+        let error: boolean = false;
+        const strFilter = "met:-1==0";
+        const exeption = "Filter could not be created: \"met:-1\" was not found";
+        try {
+            engine.parseClause(strFilter);
+        }
+        catch (e){
+            error = true;
+            expect(e.message).to.be.equal(exeption);
+
+        }
+        expect(error).to.be.true;
+    });
+    it("should throw an exception, when a operator is not found", () => {
+        let error: boolean = false;
+        let strFilter = "met:-1=?0";
+        let exeption = "Filter could not be created: Operator on \"" + strFilter + "\" could not be extracted";
+        try {
+            engine.parseClause(strFilter);
+        }
+        catch (e){
+            error = true;
+            expect(e.message).to.be.equal(exeption);
+
+        }
+        expect(error).to.be.true;
+        error = false;
+        strFilter = "met:-1!?0";
+        exeption = "Filter could not be created: Operator on \"" + strFilter + "\" could not be extracted";
+        try {
+            engine.parseClause(strFilter);
+        }
+        catch (e){
+            error = true;
+            expect(e.message).to.be.equal(exeption);
+
+        }
+        expect(error).to.be.true;
+    });
 });
diff --git a/src/core/engine.ts b/src/core/engine.ts
index b4684354dcee877d9908c7ececda68db423b599e..44fcf68eb7353bc8cefa4bd87153c2f8c63dbccb 100644
--- a/src/core/engine.ts
+++ b/src/core/engine.ts
@@ -20,6 +20,8 @@
 
 import { Dimension } from "./dimension";
 import { Metric } from "./metric";
+import { Clause } from "./clause";
+import { Filter } from "./filter";
 import { View } from "./view";
 import { Query } from "../common/query";
 import { Graph } from "../util/graph";
@@ -88,12 +90,56 @@ export class Engine {
         return result;
     }
 
+    public parseClause(strClause: string): Clause {
+        let strFilters = strClause.split(",").filter((item: string) => item !== "");
+        let filters: Filter[] = [];
+        for (let i = 0; i < strFilters.length; ++i) {
+            filters.push(this.parseFilter(strFilters[i]));
+        }
+
+        return new Clause({filters: filters});
+    }
+
+    public parseFilter(strFilter: string): Filter {
+        let segment = Filter.segment(strFilter);
+        if (segment) {
+            // Segment never returns NONE
+            let op = Filter.parseOperator(segment.operator);
+            let target: Metric|Dimension = null;
+            try {
+                target = this.getDimensionByName(segment.target);
+            }
+
+            catch (e) {
+                try {
+                    target = this.getMetricByName(segment.target);
+                }
+
+                catch (e) {
+                    target = null;
+                }
+            }
+
+            if (!target) {
+                throw new Error("Filter could not be created: \"" + segment.target + "\" was not found");
+            }
+
+            return new Filter({
+                target: target,
+                operator: op,
+                value: segment.value
+            });
+        }
+        else {
+            throw new Error("Filter could not be created: Operator on \"" + strFilter + "\" could not be extracted");
+        }
+    }
     public query (q: Query) {
         return this.selectOptimalView(q);
     }
 
     private selectOptimalView (q: Query) {
-        let optimalViews = this.graph.cover(q.metrics, q.dimensions);
+        let optimalViews = this.graph.cover(q);
         if (optimalViews.length === 0) {
             throw new Error ("Engine views cannot cover the query");
         }
@@ -111,6 +157,7 @@ export class Engine {
             let options = {
                 metrics: q.metrics,
                 dimensions: q.dimensions,
+                clauses: ((q.clauses) ? q.clauses : []),
                 materialized: false,
                 origin: false, // Never a dynamic generated view will be origin
                 childViews: optimalViews
diff --git a/src/core/filter.spec.ts b/src/core/filter.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e109d2352318cacb616025b0b062d77074c03959
--- /dev/null
+++ b/src/core/filter.spec.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 Centro de Computacao Cientifica e Software Livre
+ * Departamento de Informatica - Universidade Federal do Parana
+ *
+ * This file is part of blendb.
+ *
+ * blendb is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * blendb is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with blendb.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import { expect } from "chai";
+
+import { FilterOperator, Filter } from "./filter";
+
+describe("filter class", () => {
+    it("should correctly parse the operators", () => {
+        expect(Filter.parseOperator("==")).to.be.equal(FilterOperator.EQUAL);
+        expect(Filter.parseOperator("!=")).to.be.equal(FilterOperator.NOTEQUAL);
+        expect(Filter.parseOperator("?=")).to.be.equal(FilterOperator.NONE);
+    });
+});
diff --git a/src/core/filter.ts b/src/core/filter.ts
new file mode 100644
index 0000000000000000000000000000000000000000..cffa555af42aa8939bf51ff82e1f0b96dfc0992b
--- /dev/null
+++ b/src/core/filter.ts
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2017 Centro de Computacao Cientifica e Software Livre
+ * Departamento de Informatica - Universidade Federal do Parana
+ *
+ * This file is part of blend.
+ *
+ * blend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * blend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with blend.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import { Dimension } from "./dimension";
+import { Metric } from "./metric";
+import { Hash } from "../util/hash";
+
+export interface FilterOptions {
+    target: Metric|Dimension;
+    operator: FilterOperator;
+    value: string;
+}
+
+export interface StrFilterOptions {
+    target: string;
+    operator: string;
+    value: string;
+}
+
+export enum FilterOperator {
+    NONE,
+    EQUAL,
+    NOTEQUAL
+}
+
+export class Filter {
+    public readonly id: string;
+    public readonly target: Metric|Dimension;
+    public readonly operator: FilterOperator;
+    public readonly value: string;
+
+    constructor (options: FilterOptions) {
+        this.target = options.target;
+        this.operator = options.operator;
+        this.value = options.value;
+        this.id = Hash.sha1(options.target.name + options.operator + options.value);
+    }
+
+    public static parseOperator(op: string): FilterOperator {
+        switch (op) {
+            case "==":
+                return FilterOperator.EQUAL;
+            case "!=":
+                return FilterOperator.NOTEQUAL;
+            default:
+                return FilterOperator.NONE;
+        }
+    }
+
+    public static segment(strFilter: string): StrFilterOptions {
+        for (let i = 0; i < strFilter.length; ++i) {
+            if (strFilter[i] === "=") {
+                if (strFilter[i + 1] === "=") {
+                    return {
+                        target: strFilter.slice(0, i),
+                        operator: "==",
+                        value: strFilter.slice(i + 2)
+                    };
+                }
+
+            }
+
+            if (strFilter[i] === "!") {
+                if (strFilter[i + 1] === "=") {
+                    return {
+                        target: strFilter.slice(0, i),
+                        operator: "!=",
+                        value: strFilter.slice(i + 2)
+                    };
+                }
+
+            }
+        }
+
+        return null;
+    }
+
+}
diff --git a/src/core/view.ts b/src/core/view.ts
index 8d1f9545cf566a958c8e7c7c3dc47dba13718126..ef83f082c68f46bdf3a9f633127163b083416dfa 100644
--- a/src/core/view.ts
+++ b/src/core/view.ts
@@ -21,6 +21,7 @@
 import { Dimension } from "./dimension";
 import { Metric } from "./metric";
 import { Hash } from "../util/hash";
+import { Clause } from "./clause";
 
 export interface LoadView {
     view: View;
@@ -31,6 +32,7 @@ export interface ViewOptions {
     metrics: Metric[];
     dimensions: Dimension[];
     origin: boolean;
+    clauses?: Clause[];
     materialized?: boolean;
     childViews?: View[];
 }
@@ -39,6 +41,7 @@ export class View {
     public readonly id: string;
     public readonly metrics: Metric[];
     public readonly dimensions: Dimension[];
+    public readonly clauses: Clause[];
     public readonly materialized: boolean;
     public readonly origin: boolean;
     public childViews: View[];
@@ -46,13 +49,16 @@ export class View {
     constructor (options: ViewOptions) {
         this.metrics = options.metrics.sort();
         this.dimensions = options.dimensions.sort();
+        this.clauses = (options.clauses) ? options.clauses.sort() : [];
         this.materialized = options.materialized || false;
         this.origin = options.origin || false;
         this.childViews = (options.childViews) ? options.childViews : [];
 
         // calculate the id of the view based on it's metrics and dimensions
-        let metricsNames = options.metrics.map(metric => metric.name);
-        let dimensionsNames = options.dimensions.map(dimension => dimension.name);
-        this.id = Hash.sha1(metricsNames.concat(dimensionsNames).sort());
+        const metNames = this.metrics.map((metric) => metric.name);
+        const dimNames = this.dimensions.map((dimension) => dimension.name);
+        const clausesIds = this.clauses.map((clause) => clause.id);
+        const join = metNames.concat(dimNames).concat(clausesIds).sort();
+        this.id = Hash.sha1(join);
     }
 }
diff --git a/src/util/graph.spec.ts b/src/util/graph.spec.ts
index 268011f60260d7e769d0a189f41966d0ce513dca..aab53671b40c8425fdfa03a30f1435180b2db2ee 100644
--- a/src/util/graph.spec.ts
+++ b/src/util/graph.spec.ts
@@ -23,8 +23,11 @@ import { expect } from "chai";
 import { Metric } from "../core/metric";
 import { Dimension } from "../core/dimension";
 import { View } from "../core/view";
+import { Filter, FilterOperator } from "../core/filter";
+import { Clause } from "../core/clause";
 import { Graph } from "./graph";
 import { AggregationType, RelationType } from "../common/types";
+import { Query } from "../common/query";
 
 describe("graph class", () => {
 
@@ -197,7 +200,8 @@ describe("graph class", () => {
         });
 
         expect(g.addView(view)).to.be.true;
-        let children = g.cover([], [dim]);
+        const query: Query = { metrics: [], dimensions: [dim] };
+        let children = g.cover(query);
         expect(children).to.be.an("array");
         expect(children).to.have.length(1);
         expect(children[0].id).to.be.equal(view.id);
@@ -266,7 +270,8 @@ describe("graph class", () => {
             expect(g.addView(views[i])).to.be.true;
         }
 
-        let children = g.cover([mets[0], mets[1]], [dims[0], dims[1]]);
+        const query: Query = { metrics: [mets[0], mets[1]], dimensions: [dims[0], dims[1]] };
+        let children = g.cover(query);
         expect(children).to.be.an("array");
         expect(children).to.have.length(1);
         expect(children[0].id).to.be.equal(views[views.length - 1].id);
@@ -305,7 +310,8 @@ describe("graph class", () => {
 
         expect(g.addView(view)).to.be.true;
 
-        let children = g.cover([], [dims[1], dims[2]]);
+        const query: Query = { metrics: [], dimensions: [dims[1], dims[2]] };
+        let children = g.cover(query);
         expect(children).to.be.an("array");
         expect(children).to.have.length(1);
         expect(children[0].id).to.be.equal(view.id);
@@ -344,8 +350,70 @@ describe("graph class", () => {
 
         expect(g.addView(view)).to.be.true;
 
-        let children = g.cover([], []);
+        const query: Query = { metrics: [], dimensions: [] };
+        let children = g.cover(query);
         expect(children).to.be.an("array");
         expect(children).to.be.empty;
     });
+
+    it("should cover the graph, even when a constraint edge can not be used", () => {
+        let dims = [
+            new Dimension({name: "dim:0", dataType: "date"}),
+            new Dimension({name: "dim:1", dataType: "date"}),
+            new Dimension({name: "dim:2", dataType: "date"}),
+        ];
+
+        let filter1 = new Filter({
+            target: dims[0],
+            operator: FilterOperator.EQUAL,
+            value: "01/01/01"
+        });
+        let filter2 = new Filter({
+            target: dims[0],
+            operator: FilterOperator.EQUAL,
+            value: "01/01/02"
+        });
+        let clause1 = new Clause({filters: [filter1]});
+        let clause2 = new Clause({filters: [filter2]});
+
+        let g = new Graph();
+
+        for (let i = 0; i < 3; ++i) {
+            expect(g.addDimension(dims[i])).to.be.true;
+        }
+
+        let view1 = new View({
+            metrics: [],
+            dimensions: [dims[0], dims[1]],
+            origin: true,
+            materialized: true
+        });
+
+        let view2 = new View({
+            metrics: [],
+            dimensions: [dims[1], dims[2]],
+            origin: true,
+            materialized: true
+        });
+
+        let view3 = new View({
+            metrics: [],
+            dimensions: dims,
+            origin: false,
+            materialized: false,
+            childViews: [view1, view2],
+            clauses: [clause1]
+        });
+
+        expect(g.addView(view1)).to.be.true;
+        expect(g.addView(view2)).to.be.true;
+        expect(g.addView(view3)).to.be.true;
+
+        const query: Query = { metrics: [], dimensions: dims, clauses: [clause2] };
+        let children = g.cover(query);
+        expect(children).to.be.an("array");
+        expect(children).to.have.length(2);
+        expect(children.every((item) => item.id !==  view3.id)).to.be.true;
+    });
+
 });
diff --git a/src/util/graph.ts b/src/util/graph.ts
index da49807dc1ed500c6722306e359e81f528b9280c..881ce7df1f85a1955860cb1ac7d268be6e81cc42 100644
--- a/src/util/graph.ts
+++ b/src/util/graph.ts
@@ -21,6 +21,8 @@
 import { View } from "../core/view";
 import { Metric } from "../core/metric";
 import { Dimension } from "../core/dimension";
+import { Query } from "../common/query";
+import { Clause } from "../core/clause";
 
 enum State {
     UNVISITED,
@@ -305,7 +307,10 @@ export class Graph {
 
         If this set cannot be created, throws a error
     */
-    public cover(metrics: Metric[], dimensions: Dimension[]): View[] {
+    public cover(q: Query): View[] {
+        const metrics = q.metrics;
+        const dimensions = q.dimensions;
+        const clauses = (q.clauses) ? q.clauses : [];
         let output: View[] = [];
         let verticesIds = metrics.map((met) => met.name);
         verticesIds = verticesIds.concat(dimensions.map((dim) => dim.name));
@@ -335,7 +340,7 @@ export class Graph {
             let v: Vertex = queue.shift();
             for (let key in v.neighbors) {
                 let u: Vertex = this.verticeMap[key];
-                if (u.state === State.UNVISITED) {
+                if (this.canVisit(u, v.neighbors[key], clauses)) {
                     // Mark all vertices visited by the search
                     u.state = State.VISITED;
                     u.parent = v;
@@ -369,9 +374,11 @@ export class Graph {
             let v = this.verticeMap[verticesIds.shift()];
             while (v.parent !== null) {
                 let options = v.parent.neighbors[v.id].filter((edge) => {
-                    // Filther the edges ids to get only the ones that
-                    // represent views
-                    return edge.isView;
+                    // Filter the edges ids to get only the ones that
+                    // represent views, also get only the ones that pass
+                    // in the constraints
+                    return edge.isView &&
+                           this.passConstraints(clauses, edge.view.clauses);
                 }).map((edge) => edge.view);
                 // Check if there is a intersection between output and options
                 if (output.some((child) => options.some((view) => child === view))) {
@@ -486,4 +493,48 @@ export class Graph {
         return bestView;
     }
 
+    /*
+        Check if a vertex is can be visited from another vertex.
+        Basically checks if the vertex is unvisited, if is a sub dimension
+        or view edge and if is a view, chech the constraints.
+    */
+    private canVisit(v: Vertex, neighbors: Edge[], clauses: Clause[] ): boolean {
+        if (v.state !== State.UNVISITED) {
+            return false;
+        }
+
+        for (let i = 0; i < neighbors.length; ++i) {
+            if (neighbors[i].isView) {
+                if (this.passConstraints(clauses, neighbors[i].view.clauses)) {
+                    return true;
+                }
+            }
+
+            else {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /*
+        Check if a set of filter/clauses of a view suits for the query
+    */
+    private passConstraints(constraints: Clause[], target: Clause[]) {
+        /*
+            TODO: Enhance constraint check.
+
+            The assumption is that the constraints are simple now and only
+            check sub set is enought, but if the clauses get more complex
+            then this function should be updated.
+
+            Remember: The fact that a view cannot be choosed by constraints
+            only means that a more inneficient view must be choosen.
+        */
+
+        return target.every((item) => constraints.some((c) => c.id === item.id));
+
+    }
+
 }
diff --git a/test/scenario.ts b/test/scenario.ts
index 0a896280eccbcda089f14eb8a13e6e6ee6b39acf..04861a044df7ec3f7c4cad1ad7001aa9fb4b681a 100644
--- a/test/scenario.ts
+++ b/test/scenario.ts
@@ -22,6 +22,8 @@ import { ConfigParser } from "../src/util/configParser";
 import { Metric } from "../src/core/metric";
 import { Dimension } from "../src/core/dimension";
 import { View } from "../src/core/view";
+import { Filter, FilterOperator } from "../src/core/filter";
+import { Clause } from "../src/core/clause";
 import { AggregationType, RelationType } from "../src/common/types";
 import { Query} from "../src/common/query";
 
@@ -42,12 +44,17 @@ interface AdapterScenario {
     join4View: View;
     dateView: View;
     aggrView: View;
+    clauseView: View;
+    multiFilterView: View;
+    multiClauseView: View;
+    notEqualView: View;
 }
 
 interface DataCtrlScenario {
     wrongMet: Query;
     wrongDim: Query;
     correct: Query;
+    clausal: Query;
 }
 
 const config = ConfigParser.parse("config/test.yaml");
@@ -56,6 +63,35 @@ const mets = config.metrics;
 const dims = config.dimensions;
 const views = config.views;
 
+const filters: { [key: string]: Filter } = {
+    "dim:0:0" : new Filter({
+        target: dims[0],
+        operator: FilterOperator.EQUAL,
+        value: "2017-01-02"
+    }),
+    "dim:0:1" : new Filter({
+        target: dims[0],
+        operator: FilterOperator.EQUAL,
+        value: "2017-01-03"
+    }),
+    "dim:3" : new Filter({
+        target: dims[3],
+        operator: FilterOperator.NOTEQUAL,
+        value: "dim:3:1"
+    }),
+    "dim:7" : new Filter({
+        target: dims[7],
+        operator: FilterOperator.EQUAL,
+        value: "1"
+    })
+};
+
+const clauses: { [key: string]: Clause }  = {
+    "view0dim7": new Clause({filters: [filters["dim:7"]]}),
+    "view0dim0": new Clause({filters: [filters["dim:0:0"], filters["dim:0:1"]]}),
+    "view3dim3": new Clause({filters: [filters["dim:3"]]})
+};
+
 const wrongMet = new Metric({
     name: "met:11",
     aggregation: AggregationType.COUNT,
@@ -141,6 +177,42 @@ const aggrView = new View({
     childViews: [views[0], views[2], views[4]]
 });
 
+const clauseView = new View({
+    metrics: [mets[0], mets[1], mets[2]],
+    dimensions: [dims[0]],
+    materialized: false,
+    origin: false,
+    childViews: [views[0]],
+    clauses: [clauses.view0dim7]
+});
+
+const multiFilterView = new View({
+    metrics: [mets[0], mets[1]],
+    dimensions: [dims[0]],
+    materialized: false,
+    origin: false,
+    childViews: [views[0]],
+    clauses: [clauses.view0dim0]
+});
+
+const multiClauseView = new View({
+    metrics: [mets[0], mets[1]],
+    dimensions: [dims[0]],
+    materialized: false,
+    origin: false,
+    childViews: [views[0]],
+    clauses: [clauses.view0dim0, clauses.view0dim7]
+});
+
+const notEqualView = new View({
+    metrics: [],
+    dimensions: [dims[3]],
+    materialized: false,
+    origin: false,
+    childViews: [views[3]],
+    clauses: [clauses.view3dim3]
+});
+
 const subDimView = new View({
     metrics: [mets[0]],
     dimensions: [subdims[0], subdims[1], dims[7], dims[8]],
@@ -189,11 +261,16 @@ export const adapterScenario: AdapterScenario = {
     subDimensionView: subDimView,
     join4View: join4View,
     dateView: dateView,
-    aggrView: aggrView
+    aggrView: aggrView,
+    clauseView: clauseView,
+    multiFilterView: multiFilterView,
+    multiClauseView: multiClauseView,
+    notEqualView: notEqualView
 };
 
 export const dataCtrlScenario: DataCtrlScenario = {
     wrongMet: { metrics: [wrongMet], dimensions: [dims[0]] },
     wrongDim: { metrics: [mets[0]], dimensions: [wrongDim] },
-    correct: { metrics: [mets[0]], dimensions: [dims[0]] }
+    correct: { metrics: [mets[0]], dimensions: [dims[0]] },
+    clausal: { metrics: [mets[0]], dimensions: [dims[7]] }
 };