diff --git a/db.go b/db.go
index 80e6288ddc2f6edf2549a489dd3d1e43475c0fbb..fcea7e56486a08e981b7f6ecf579c95b6c0b0047 100644
--- a/db.go
+++ b/db.go
@@ -62,7 +62,21 @@ import (
 //
 //	Where age is lower than 18 (On MongoDB context).
 //	db.Cond { "age $lt": 18 }
-type Cond map[string]interface{}
+type Cond builder.M
+
+func (m Cond) Constraints() []builder.Constraint {
+	return builder.M(m).Constraints()
+}
+
+func (m Cond) Operator() builder.CompoundOperator {
+	return builder.M(m).Operator()
+}
+
+func (m Cond) Sentences() []builder.Compound {
+	return builder.M(m).Sentences()
+}
+
+/*map[string]interface{}
 
 func (m Cond) Constraints() []builder.Constraint {
 	c := make([]builder.Constraint, 0, len(m))
@@ -71,6 +85,7 @@ func (m Cond) Constraints() []builder.Constraint {
 	}
 	return c
 }
+*/
 
 // Func is a struct that represents database functions.
 //
@@ -124,20 +139,7 @@ func Func(name string, args ...interface{}) builder.Function {
 // 		},
 // 		db.Cond{ "last_name": "Mouse" },
 // 	}
-type And []builder.Constraints
-
-// And adds a new expression to an And conditions array.
-func (a And) And(t ...builder.Constraints) And {
-	return append(a, t...)
-}
-
-func (a And) Constraints() []builder.Constraints {
-	return a
-}
-
-func (a And) Operator() builder.ConstraintOperator {
-	return builder.OperatorAnd
-}
+var And = builder.And
 
 // Or is an array of interfaced that is used to join two or more expressions
 // under logical disjunction, it accepts `db.Cond{}`, `db.And{}`, `db.Raw{}`
@@ -150,20 +152,7 @@ func (a And) Operator() builder.ConstraintOperator {
 // 		db.Cond{"year": 2012},
 // 		db.Cond{"year": 1987},
 // 	}
-type Or []builder.Constraints
-
-// Or adds a new expression to an Or conditions array.
-func (o Or) Or(t ...builder.Constraints) Or {
-	return append(o, t...)
-}
-
-func (o Or) Constraints() []builder.Constraints {
-	return o
-}
-
-func (o Or) Operator() builder.ConstraintOperator {
-	return builder.OperatorOr
-}
+var Or = builder.Or
 
 // Raw holds chunks of data to be passed to the database without any filtering.
 // Use with care.
@@ -410,7 +399,6 @@ type Constrainer interface {
 
 var (
 	_ = builder.Constraints(Cond{})
-	_ = builder.Criteria(And{})
-	_ = builder.Criteria(Or{})
+	_ = builder.Compound(Cond{})
 	_ = builder.Function(&dbFunc{})
 )
diff --git a/db_test.go b/db_test.go
index f389fc15496d0771dc9ec1e8761e4f72a0c82c4f..62646f59f908412cf0975342df40f661ee6b779f 100644
--- a/db_test.go
+++ b/db_test.go
@@ -718,13 +718,13 @@ func TestFibonacci(t *testing.T) {
 			// Testing sorting by function.
 			res = col.Find(
 				// 5, 6, 7, 3
-				db.Or{
-					db.And{
+				db.Or(
+					db.And(
 						db.Cond{"input >=": 5},
 						db.Cond{"input <=": 7},
-					},
+					),
 					db.Cond{"input": 3},
-				},
+				),
 			)
 
 			// Testing sort by function.
@@ -748,16 +748,7 @@ func TestFibonacci(t *testing.T) {
 			}
 
 			// Find() with IN/$in
-			var whereIn db.Cond
-
-			switch wrapper {
-			case `mongo`:
-				whereIn = db.Cond{"input": db.Func("$in", 3, 5, 6, 7)}
-			default:
-				whereIn = db.Cond{"input": db.Func("IN", 3, 5, 6, 7)}
-			}
-
-			res = col.Find(whereIn).Sort("input")
+			res = col.Find(db.Cond{"input IN": []int{3, 5, 6, 7}}).Sort("input")
 
 			total, err = res.Count()
 
@@ -794,13 +785,13 @@ func TestFibonacci(t *testing.T) {
 			// Find() with range
 			res = col.Find(
 				// 5, 6, 7, 3
-				db.Or{
-					db.And{
+				db.Or(
+					db.And(
 						db.Cond{"input >=": 5},
 						db.Cond{"input <=": 7},
-					},
+					),
 					db.Cond{"input": 3},
-				},
+				),
 			).Sort("-input")
 
 			if total, err = res.Count(); err != nil {
@@ -866,7 +857,7 @@ func TestFibonacci(t *testing.T) {
 				}
 
 				// Find() with empty expression
-				res1b := col.Find(db.Or{db.And{db.Cond{}, db.Cond{}}, db.Or{db.Cond{}}})
+				res1b := col.Find(db.Or(db.And(db.Cond{}, db.Cond{}), db.Or(db.Cond{})))
 				total, err = res1b.Count()
 
 				if total != 6 {
diff --git a/mongo/benchmark_test.go b/mongo/benchmark_test.go
index 3b23101f5d30402c0e3e743c4fef215462012e17..d915985bb9d0f7c6c01912c3e0ce3eaa40c7d5d4 100644
--- a/mongo/benchmark_test.go
+++ b/mongo/benchmark_test.go
@@ -262,11 +262,11 @@ func BenchmarkUpperFindAll(b *testing.B) {
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		res := artist.Find(db.Or{
+		res := artist.Find(db.Or(
 			db.Cond{"name": artistN(i)},
 			db.Cond{"name": artistN(i + 1)},
 			db.Cond{"name": artistN(i + 2)},
-		})
+		))
 		if err = res.All(&items); err != nil {
 			b.Fatal(err)
 		}
diff --git a/mongo/collection.go b/mongo/collection.go
index c5fa1d69a82828a8f45c342e788e8a66af2c5a75..b5a366ea36303c4efe362f267156b4efb87a159a 100644
--- a/mongo/collection.go
+++ b/mongo/collection.go
@@ -23,6 +23,7 @@ package mongo
 
 import (
 	"fmt"
+	"log"
 	"strings"
 	"sync"
 
@@ -88,11 +89,16 @@ func compileStatement(cond db.Cond) bson.M {
 		field = strings.TrimSpace(field)
 
 		chunks := strings.SplitN(field, ` `, 2)
+		log.Printf("chunks: %#v", chunks)
 
 		var op string
 
 		if len(chunks) > 1 {
 			switch chunks[1] {
+			case `IN`:
+				op = `$in`
+			case `NOT IN`:
+				op = `$nin`
 			case `>`:
 				op = `$gt`
 			case `<`:
@@ -106,15 +112,10 @@ func compileStatement(cond db.Cond) bson.M {
 			}
 		}
 
-		switch value := value.(type) {
-		case builder.Function:
-			conds[chunks[0]] = bson.M{value.Name(): value.Arguments()}
-		default:
-			if op == "" {
-				conds[chunks[0]] = value
-			} else {
-				conds[chunks[0]] = bson.M{op: value}
-			}
+		if op == "" {
+			conds[chunks[0]] = value
+		} else {
+			conds[chunks[0]] = bson.M{op: value}
 		}
 
 	}
@@ -138,24 +139,26 @@ func (col *Collection) compileConditions(term interface{}) interface{} {
 		if len(values) > 0 {
 			return values
 		}
-	case db.Or:
-		values := []interface{}{}
-		for i := range t {
-			values = append(values, col.compileConditions(t[i]))
-		}
-		condition := bson.M{`$or`: values}
-		return condition
-	case db.And:
-		values := []interface{}{}
-		for i := range t {
-			values = append(values, col.compileConditions(t[i]))
-		}
-		condition := bson.M{`$and`: values}
-		return condition
 	case db.Cond:
 		return compileStatement(t)
 	case db.Constrainer:
 		return compileStatement(t.Constraints())
+	case builder.Compound:
+		values := []interface{}{}
+
+		for _, s := range t.Sentences() {
+			values = append(values, col.compileConditions(s))
+		}
+
+		var op string
+		switch t.Operator() {
+		case builder.OperatorOr:
+			op = `$or`
+		default:
+			op = `$and`
+		}
+
+		return bson.M{op: values}
 	}
 	return nil
 }
diff --git a/mongo/database_test.go b/mongo/database_test.go
index 6380d8cdc31b6215358359ef69238cce404bd0fc..e22b3434b8591a6782bd88480b204da1404c57a0 100644
--- a/mongo/database_test.go
+++ b/mongo/database_test.go
@@ -816,8 +816,7 @@ func TestUpdate(t *testing.T) {
 
 }
 
-// Test database functions
-func TestFunction(t *testing.T) {
+func TestOperators(t *testing.T) {
 	var err error
 	var res db.Result
 
@@ -843,13 +842,7 @@ func TestFunction(t *testing.T) {
 		Name string
 	}{}
 
-	res = artist.Find(db.Cond{"_id $nin": []int{0, -1}})
-
-	if err = res.One(&rowS); err != nil {
-		t.Fatalf("One: %q", err)
-	}
-
-	res = artist.Find(db.Cond{"_id": db.Func("$nin", 0, -1)})
+	res = artist.Find(db.Cond{"_id NOT IN": []int{0, -1}})
 
 	if err = res.One(&rowS); err != nil {
 		t.Fatalf("One: %q", err)
diff --git a/mysql/benchmark_test.go b/mysql/benchmark_test.go
index 57ad6cc995fa81a4d3f81fbc35d7e99c5eb44a08..8aa1803cdc6832dc71452bbcf119e3d69d31832b 100644
--- a/mysql/benchmark_test.go
+++ b/mysql/benchmark_test.go
@@ -528,11 +528,11 @@ func BenchmarkUpperFindAll(b *testing.B) {
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		res := artist.Find(db.Or{
+		res := artist.Find(db.Or(
 			db.Cond{"name": artistN(i)},
 			db.Cond{"name": artistN(i + 1)},
 			db.Cond{"name": artistN(i + 2)},
-		})
+		))
 		if err = res.All(&items); err != nil {
 			b.Fatal(err)
 		}
diff --git a/postgresql/benchmark_test.go b/postgresql/benchmark_test.go
index 1402f590443aff1f93108eed5a0cd4b8e7bfade2..dff2de1e14d8a1cbb21d31b31bcc5f61249d7d08 100644
--- a/postgresql/benchmark_test.go
+++ b/postgresql/benchmark_test.go
@@ -540,11 +540,11 @@ func BenchmarkUpperFindAll(b *testing.B) {
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		res := artist.Find(db.Or{
+		res := artist.Find(db.Or(
 			db.Cond{"name": artistN(i)},
 			db.Cond{"name": artistN(i + 1)},
 			db.Cond{"name": artistN(i + 2)},
-		})
+		))
 		if err = res.All(&items); err != nil {
 			b.Fatal(err)
 		}
diff --git a/ql/benchmark_test.go b/ql/benchmark_test.go
index f763f7b298a9cb63ff0aa3341a57b433a91154af..9e35c90e88b840d1d3ff12d8f84c19b7f8759175 100644
--- a/ql/benchmark_test.go
+++ b/ql/benchmark_test.go
@@ -607,11 +607,11 @@ func BenchmarkUpperFindAll(b *testing.B) {
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		res := artist.Find(db.Or{
+		res := artist.Find(db.Or(
 			db.Cond{"name": artistN(i)},
 			db.Cond{"name": artistN(i + 1)},
 			db.Cond{"name": artistN(i + 2)},
-		})
+		))
 		if err = res.All(&items); err != nil {
 			b.Fatal(err)
 		}
diff --git a/sqlite/benchmark_test.go b/sqlite/benchmark_test.go
index b52339a42238fc294989097834131ea398ab5a91..e312e972a4aa50deada7d10190a2ab48df28caff 100644
--- a/sqlite/benchmark_test.go
+++ b/sqlite/benchmark_test.go
@@ -528,11 +528,11 @@ func BenchmarkUpperFindAll(b *testing.B) {
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		res := artist.Find(db.Or{
+		res := artist.Find(db.Or(
 			db.Cond{"name": artistN(i)},
 			db.Cond{"name": artistN(i + 1)},
 			db.Cond{"name": artistN(i + 2)},
-		})
+		))
 		if err = res.All(&items); err != nil {
 			b.Fatal(err)
 		}