def find(self, filter={}, fields=None, skip=0, limit=None, sort=None):
        """
        Searches the table using the filters provided.
        
        :Examples:

        >>> users = user_table.find({'id': {'$in': [10, 20]}, 'age': {'$gt': 20}}) # Complex query
        >>> user_count = len(users)
        >>> for user in users:
        >>>     # Do something...
        >>>     print user.id
        >>> 
        >>> users = user_table.find({}, sort=[('age', monsql.ASCENDING)]) # sort by age

        Also support complex operators:

        >>> {a: 1}                                  # a == 1
        >>> {a: {$gt: 1}}                           # a > 1
        >>> {a: {$gte: 1}}                          # a >= 1
        >>> {a: {$lt: 1}}                           # a < 1
        >>> {a: {$lte: 1}}                          # a <= 1
        >>> {a: {$eq: 1}}                           # a == 1
        >>> {a: {$in: [1, 2]}}                      # a == 1 or a == 2
        >>> {a: {$contains: '123'}}                 # a like %123%
        >>> {$not: condition}                       # !(condition)
        >>> {$and: [condition1, condition2, ...]}   # condition1 and condition2
        >>> {$or: [condition1, condition2, ...]}    # condition1 or condition2

        :Parameters: 

        - query(dict): specify the WHERE clause. One example is {"name": "...", "id": ...}    
        - fields: specify what fields are needed
        - skip, limit: both integers, skip without defining limit is meaningless
        - sort: A list, each element is a two-item tuple, with the first item be the column name
          and the second item be either monsql.ASCENDING or monsql.DESCENDING

        :Return: a QuerySet object
        """
        if not fields:
            self.__ensure_columns()
            fields = self.columns

        query_obj = Query(source=self.name, filter=filter, fields=fields, skip=skip, limit=limit, sort=sort)
        return QuerySet(cursor=self.cursor, query=query_obj)