elts) {
+        first = pg.isFirst();
+        last = pg.isLast();
+        currentPage = pg.getNumber() + 1;
+        pageSize = pg.getSize();
+        totalPages = pg.getTotalPages();
+        totalItems = pg.getTotalElements();
+        itemsPerPage = pg.getNumberOfElements();
+        items = elts;
+    }
+
+
+}
diff --git a/src/main/java/com/tutorial/springdatamongodbdynamicqueries/controller/dto/FilterCondition.java b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/controller/dto/FilterCondition.java
new file mode 100644
index 0000000..0a86f1f
--- /dev/null
+++ b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/controller/dto/FilterCondition.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019. @aek - (anicetkeric@gmail.com)
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package com.tutorial.springdatamongodbdynamicqueries.controller.dto;
+
+import com.tutorial.springdatamongodbdynamicqueries.enums.FilterOperationEnum;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+
+/**
+ * FilterCondition
+ *
+ * @author aek
+ * 
+ * Description: Filter Condition Class
+ */
+@Setter
+@Getter
+@AllArgsConstructor
+@RequiredArgsConstructor
+public class FilterCondition {
+
+    private String field;
+    private FilterOperationEnum operator;
+    private Object value;
+
+}
diff --git a/src/main/java/com/tutorial/springdatamongodbdynamicqueries/domain/Department.java b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/domain/Department.java
new file mode 100644
index 0000000..e6756b5
--- /dev/null
+++ b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/domain/Department.java
@@ -0,0 +1,17 @@
+package com.tutorial.springdatamongodbdynamicqueries.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.NonNull;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class Department {
+
+    @NonNull
+    private String code;
+
+    private String name;
+}
diff --git a/src/main/java/com/tutorial/springdatamongodbdynamicqueries/domain/Employee.java b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/domain/Employee.java
new file mode 100644
index 0000000..833fa56
--- /dev/null
+++ b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/domain/Employee.java
@@ -0,0 +1,27 @@
+package com.tutorial.springdatamongodbdynamicqueries.domain;
+
+import lombok.*;
+import lombok.experimental.Accessors;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+@Builder
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Accessors(chain = true)
+@Document(collection = "employee")
+public class Employee {
+
+    @Id
+    private String id;
+
+    private String firstName;
+
+    private String lastName;
+
+    private String email;
+
+    @NonNull
+    private Department department;
+}
\ No newline at end of file
diff --git a/src/main/java/com/tutorial/springdatamongodbdynamicqueries/enums/FilterOperationEnum.java b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/enums/FilterOperationEnum.java
new file mode 100644
index 0000000..bba142a
--- /dev/null
+++ b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/enums/FilterOperationEnum.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2019. @aek - (anicetkeric@gmail.com)
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package com.tutorial.springdatamongodbdynamicqueries.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+
+/**
+ * 
FilterOperation
+ *
+ * @author aek
+ * 
+ * Description:
+ */
+public enum FilterOperationEnum {
+
+    EQUAL("eq"),
+    NOT_EQUAL("neq"),
+    GREATER_THAN("gt"),
+    GREATER_THAN_OR_EQUAL_TO("gte"),
+    LESS_THAN("lt"),
+    LESSTHAN_OR_EQUAL_TO("lte"),
+    IN("in"),
+    NOT_IN("nin"),
+    BETWEEN("btn"),
+    CONTAINS("like"),
+    NOT_CONTAINS("notLike"),
+    IS_NULL("isnull"),
+    IS_NOT_NULL("isnotnull"),
+    START_WITH("startwith"),
+    END_WITH("endwith"),
+    IS_EMPTY("isempty"),
+    IS_NOT_EMPTY("isnotempty"),
+    JOIN("jn"),
+    IS("is");
+
+
+    private final String value;
+
+    FilterOperationEnum(String value) {
+        this.value = value;
+    }
+
+    @Override
+    @JsonValue
+    public String toString() {
+        return String.valueOf(value);
+    }
+
+    public static FilterOperationEnum fromValue(String value) {
+        for (FilterOperationEnum op : FilterOperationEnum.values()) {
+
+            //Case insensitive operation name
+            if (String.valueOf(op.value).equalsIgnoreCase(value)) {
+                return op;
+            }
+        }
+        return null;
+    }
+
+}
diff --git a/src/main/java/com/tutorial/springdatamongodbdynamicqueries/repository/EmployeeRepository.java b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/repository/EmployeeRepository.java
new file mode 100644
index 0000000..1546d07
--- /dev/null
+++ b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/repository/EmployeeRepository.java
@@ -0,0 +1,8 @@
+package com.tutorial.springdatamongodbdynamicqueries.repository;
+
+import com.tutorial.springdatamongodbdynamicqueries.domain.Employee;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface EmployeeRepository extends ResourceRepository {
+}
diff --git a/src/main/java/com/tutorial/springdatamongodbdynamicqueries/repository/ResourceRepository.java b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/repository/ResourceRepository.java
new file mode 100644
index 0000000..0075036
--- /dev/null
+++ b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/repository/ResourceRepository.java
@@ -0,0 +1,18 @@
+package com.tutorial.springdatamongodbdynamicqueries.repository;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.repository.MongoRepository;
+import org.springframework.data.repository.NoRepositoryBean;
+
+import java.io.Serializable;
+import java.util.List;
+
+@NoRepositoryBean
+public interface ResourceRepository extends MongoRepository {
+
+    Page findAll(Query query, Pageable pageable);
+
+    List findAll(Query query);
+}
\ No newline at end of file
diff --git a/src/main/java/com/tutorial/springdatamongodbdynamicqueries/repository/support/GenericFilterCriteriaBuilder.java b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/repository/support/GenericFilterCriteriaBuilder.java
new file mode 100644
index 0000000..3e81ca3
--- /dev/null
+++ b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/repository/support/GenericFilterCriteriaBuilder.java
@@ -0,0 +1,94 @@
+package com.tutorial.springdatamongodbdynamicqueries.repository.support;
+
+import com.tutorial.springdatamongodbdynamicqueries.controller.dto.FilterCondition;
+import org.bson.types.ObjectId;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * This class is used to build all the queries passed as parameters.
+ * filterAndConditions (filter list for the AND operator)
+ * filterOrConditions (filter list for the OR operator)
+ */
+public class GenericFilterCriteriaBuilder {
+
+    private final List filterAndConditions;
+    private final List filterOrConditions;
+
+    private static final Map>
+            FILTER_CRITERIA = new HashMap<>();
+
+    // Create map of filter
+    static {
+        FILTER_CRITERIA.put("EQUAL", condition -> Criteria.where(condition.getField()).is(condition.getValue()));
+        FILTER_CRITERIA.put("NOT_EQUAL", condition -> Criteria.where(condition.getField()).ne(condition.getValue()));
+        FILTER_CRITERIA.put("GREATER_THAN", condition -> Criteria.where(condition.getField()).gt(condition.getValue()));
+        FILTER_CRITERIA.put("GREATER_THAN_OR_EQUAL_TO", condition -> Criteria.where(condition.getField()).gte(condition.getValue()));
+        FILTER_CRITERIA.put("LESS_THAN", condition -> Criteria.where(condition.getField()).lt(condition.getValue()));
+        FILTER_CRITERIA.put("LESSTHAN_OR_EQUAL_TO", condition -> Criteria.where(condition.getField()).lte(condition.getValue()));
+        FILTER_CRITERIA.put("CONTAINS", condition -> Criteria.where(condition.getField()).regex((String) condition.getValue()));
+        FILTER_CRITERIA.put("JOIN", condition -> Criteria.where(condition.getField()).is(new ObjectId((String) condition.getValue())));
+    }
+
+
+    public GenericFilterCriteriaBuilder() {
+        filterOrConditions = new ArrayList<>();
+        filterAndConditions = new ArrayList<>();
+    }
+
+    public Query addCondition(List andConditions, List orConditions) {
+
+        if (andConditions != null && !andConditions.isEmpty()) {
+            filterAndConditions.addAll(andConditions);
+        }
+        if (orConditions != null && !orConditions.isEmpty()) {
+            filterOrConditions.addAll(orConditions);
+        }
+
+        List criteriaAndClause = new ArrayList<>();
+        List criteriaOrClause = new ArrayList<>();
+        Criteria criteria = new Criteria();
+
+        // build criteria
+        filterAndConditions.stream().map(condition -> criteriaAndClause.add(buildCriteria(condition))).collect(Collectors.toList());
+        filterOrConditions.stream().map(condition -> criteriaOrClause.add(buildCriteria(condition))).collect(Collectors.toList());
+
+
+        if (!criteriaAndClause.isEmpty() && !criteriaOrClause.isEmpty()) {
+            return new Query(criteria.andOperator(criteriaAndClause.toArray(new Criteria[0])).orOperator(criteriaOrClause.toArray(new Criteria[0])));
+        } else if (!criteriaAndClause.isEmpty()) {
+            return new Query(criteria.andOperator(criteriaAndClause.toArray(new Criteria[0])));
+        } else if (!criteriaOrClause.isEmpty()) {
+            return new Query(criteria.orOperator(criteriaOrClause.toArray(new Criteria[0])));
+        } else {
+            return new Query();
+        }
+
+    }
+
+
+    /**
+     * Build the predicate according to the request
+     *
+     * @param condition The condition of the filter requested by the query
+     * @return {{@link Criteria}}
+     */
+    private Criteria buildCriteria(FilterCondition condition) {
+        Function
+                function = FILTER_CRITERIA.get(condition.getOperator().name());
+
+        if (function == null) {
+            throw new IllegalArgumentException("Invalid function param type: ");
+        }
+
+        return function.apply(condition);
+    }
+
+}
diff --git a/src/main/java/com/tutorial/springdatamongodbdynamicqueries/repository/support/ResourceRepositoryImpl.java b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/repository/support/ResourceRepositoryImpl.java
new file mode 100644
index 0000000..e78fe2e
--- /dev/null
+++ b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/repository/support/ResourceRepositoryImpl.java
@@ -0,0 +1,43 @@
+package com.tutorial.springdatamongodbdynamicqueries.repository.support;
+
+import com.tutorial.springdatamongodbdynamicqueries.repository.ResourceRepository;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
+import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;
+import org.springframework.util.Assert;
+
+import java.io.Serializable;
+import java.util.List;
+
+public class ResourceRepositoryImpl extends SimpleMongoRepository implements ResourceRepository {
+
+    private MongoOperations mongoOperations;
+    private MongoEntityInformation entityInformation;
+
+    public ResourceRepositoryImpl(final MongoEntityInformation entityInformation, final MongoOperations mongoOperations) {
+        super(entityInformation, mongoOperations);
+
+        this.entityInformation = entityInformation;
+        this.mongoOperations = mongoOperations;
+    }
+
+    @Override
+    public Page findAll(final Query query, final Pageable pageable) {
+        Assert.notNull(query, "Query must not be null!");
+
+        long total = mongoOperations.count(query, entityInformation.getJavaType(), entityInformation.getCollectionName());
+        List content = mongoOperations.find(query.with(pageable), entityInformation.getJavaType(), entityInformation.getCollectionName());
+
+        return new PageImpl(content, pageable, total);
+    }
+
+    @Override
+    public List findAll(Query query) {
+        Assert.notNull(query, "Query must not be null!");
+        return mongoOperations.find(query, entityInformation.getJavaType(), entityInformation.getCollectionName());
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/tutorial/springdatamongodbdynamicqueries/service/EmployeeService.java b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/service/EmployeeService.java
new file mode 100644
index 0000000..5978438
--- /dev/null
+++ b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/service/EmployeeService.java
@@ -0,0 +1,28 @@
+package com.tutorial.springdatamongodbdynamicqueries.service;
+
+
+import com.tutorial.springdatamongodbdynamicqueries.domain.Employee;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.mongodb.core.query.Query;
+
+import java.util.List;
+
+public interface EmployeeService {
+
+
+    /**
+     * @param query custom query
+     * @return list of Employee
+     */
+    List getAll(Query query);
+
+    /**
+     * Get all custom paginate data for entity Employee
+     *
+     * @param query    custom query
+     * @param pageable pageable param
+     * @return Page of entity Employee
+     */
+    Page getPage(Query query, Pageable pageable);
+}
\ No newline at end of file
diff --git a/src/main/java/com/tutorial/springdatamongodbdynamicqueries/service/EmployeeServiceImpl.java b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/service/EmployeeServiceImpl.java
new file mode 100644
index 0000000..bd33999
--- /dev/null
+++ b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/service/EmployeeServiceImpl.java
@@ -0,0 +1,37 @@
+package com.tutorial.springdatamongodbdynamicqueries.service;
+
+import com.tutorial.springdatamongodbdynamicqueries.domain.Employee;
+import com.tutorial.springdatamongodbdynamicqueries.repository.EmployeeRepository;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class EmployeeServiceImpl implements EmployeeService {
+
+    private final EmployeeRepository employeeRepository;
+
+    public EmployeeServiceImpl(EmployeeRepository employeeRepository) {
+        this.employeeRepository = employeeRepository;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List getAll(Query query) {
+        return employeeRepository.findAll(query);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Page getPage(Query query, Pageable pageable) {
+        return employeeRepository.findAll(query, pageable);
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/tutorial/springdatamongodbdynamicqueries/service/FilterBuilderService.java b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/service/FilterBuilderService.java
new file mode 100644
index 0000000..c6c70d0
--- /dev/null
+++ b/src/main/java/com/tutorial/springdatamongodbdynamicqueries/service/FilterBuilderService.java
@@ -0,0 +1,100 @@
+package com.tutorial.springdatamongodbdynamicqueries.service;
+
+import com.tutorial.springdatamongodbdynamicqueries.controller.dto.FilterCondition;
+import com.tutorial.springdatamongodbdynamicqueries.enums.FilterOperationEnum;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * Service for Filtering Page
+ * This class is used to extract any filters requested by the client.
+ */
+@Service
+public class FilterBuilderService {
+
+    private static final int DEFAULT_SIZE_PAGE = 20;
+
+
+    /**
+     * Prepare filter condition.  extract the different filters used in the controller via @RequestParam
+     *
+     * @param criteria search Criteria.
+     * @return a list of {@link FilterCondition}
+     */
+    public List createFilterCondition(String criteria) {
+        // TODO ajouter try catch
+
+
+        List filters = new ArrayList<>();
+
+        if (criteria != null && !criteria.isEmpty()) {
+
+            final String FILTER_SHEARCH_DELIMITER = "&";
+            final String FILTER_CONDITION_DELIMITER = "\\|";
+
+            List values = split(criteria, FILTER_SHEARCH_DELIMITER);
+            if (!values.isEmpty()) {
+                values.forEach(x -> {
+                    List filter = split(x, FILTER_CONDITION_DELIMITER);
+                    if (FilterOperationEnum.fromValue(filter.get(1)) != null) {
+                        filters.add(new FilterCondition(filter.get(0), FilterOperationEnum.fromValue(filter.get(1)), filter.get(2)));
+                    }
+                });
+            }
+        }
+
+        return filters;
+    }
+
+
+    private static List split(String search, String delimiter) {
+        return Stream.of(search.split(delimiter))
+                .collect(Collectors.toList());
+    }
+
+
+    /**
+     * Get request pageable. Page Request Builder. custom pageable
+     *
+     * @param size  the number of items to collect
+     * @param page  page number
+     * @param order search order filter (eg: field|ASC)
+     * @return PageRequest
+     */
+    public PageRequest getPageable(int size, int page, String order) {
+        // TODO ajouter try catch
+
+        int pageSize = (size <= 0) ? DEFAULT_SIZE_PAGE : size;
+        int currentPage = (page <= 0) ? 1 : page;
+
+        if (order != null && !order.isEmpty()) {
+
+            final String FILTER_CONDITION_DELIMITER = "\\|";
+
+            List values = split(order, FILTER_CONDITION_DELIMITER);
+            String column = values.get(0);
+            String sortDirection = values.get(1);
+
+            if (sortDirection.equalsIgnoreCase("ASC")) {
+                return PageRequest.of((currentPage - 1), pageSize, Sort.by(Sort.Direction.ASC, column));
+            } else if (sortDirection.equalsIgnoreCase("DESC")) {
+                return PageRequest.of((currentPage - 1), pageSize, Sort.by(Sort.Direction.DESC, column));
+            } else {
+                throw new IllegalArgumentException(String.format("Value for param 'order' is not valid : %s , must be 'asc' or 'desc'", sortDirection));
+            }
+
+        }else {
+            return PageRequest.of((currentPage - 1), pageSize);
+        }
+    }
+
+
+
+
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
new file mode 100644
index 0000000..db10723
--- /dev/null
+++ b/src/main/resources/application.yml
@@ -0,0 +1,8 @@
+spring:
+  data:
+    mongodb:
+      host: localhost
+      port: 27017
+      database: mongo_dynamic_search
+      username: admin
+      password: 7MlG8f&H
\ No newline at end of file
diff --git a/src/test/java/com/tutorial/springdatamongodbdynamicqueries/SpringDataMongodbDynamicQueriesApplicationTests.java b/src/test/java/com/tutorial/springdatamongodbdynamicqueries/SpringDataMongodbDynamicQueriesApplicationTests.java
new file mode 100644
index 0000000..db46bda
--- /dev/null
+++ b/src/test/java/com/tutorial/springdatamongodbdynamicqueries/SpringDataMongodbDynamicQueriesApplicationTests.java
@@ -0,0 +1,13 @@
+package com.tutorial.springdatamongodbdynamicqueries;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class SpringDataMongodbDynamicQueriesApplicationTests {
+
+    @Test
+    void contextLoads() {
+    }
+
+}