CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-cloudant

IBM Cloudant Python client library providing comprehensive interface for Cloudant and CouchDB databases

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

query-indexing.mddocs/

Query and Indexing

Query documents using Cloudant Query (Mango) with comprehensive indexing support including JSON indexes, text search, and special indexes with pagination and partitioning capabilities.

Capabilities

Query Class

Execute queries using Cloudant Query (Mango) syntax.

class Query:
    """
    Cloudant query interface using Mango query language.
    """
    
    def __init__(self, database, selector=None, fields=None, **kwargs):
        """
        Initialize query builder.
        
        Parameters:
        - database (CloudantDatabase): Target database
        - selector (dict): Query selector (WHERE clause)
        - fields (list[str]): Fields to return (SELECT clause)
        - sort (list[dict]): Sort specification
        - limit (int): Maximum results
        - skip (int): Number of results to skip
        - bookmark (str): Pagination bookmark
        - use_index (str | list): Index to use for query
        - execution_stats (bool): Include execution statistics
        """
    
    def __call__(self, **kwargs):
        """
        Execute query with optional parameter overrides.
        
        Parameters:
        - **kwargs: Query parameters to override
        
        Returns:
        QueryResult: Query result iterator with bookmark support
        """
    
    def custom_result(self, **options):
        """
        Execute query with custom result options.
        
        Parameters:
        - **options: Result collection options
        
        Returns:
        QueryResult: Custom result iterator
        """
    
    @property
    def result(self):
        """Default query result collection"""

Database Query Methods

Direct query execution methods on database instances.

class CouchDatabase(dict):
    """Database query methods."""
    
    def get_query_result(self, selector, fields=None, raw_result=False, **kwargs):
        """
        Execute Cloudant Query and return results.
        
        Parameters:
        - selector (dict): Query selector using MongoDB-style syntax
        - fields (list[str]): Fields to return in results
        - raw_result (bool): Return raw response without processing
        - sort (list[dict]): Sort specification [{"field": "asc|desc"}]
        - limit (int): Maximum number of results
        - skip (int): Number of results to skip
        - bookmark (str): Pagination bookmark from previous query
        - use_index (str | list): Force use of specific index
        - execution_stats (bool): Include query execution statistics
        
        Returns:
        QueryResult | dict: Query results or raw response
        
        Raises:
        CloudantDatabaseException: Query execution failed
        """
    
    def get_partitioned_query_result(self, partition_key, selector, fields=None, raw_result=False, **kwargs):
        """
        Execute query within a specific partition.
        
        Parameters:
        - partition_key (str): Partition identifier
        - selector (dict): Query selector
        - fields (list[str]): Fields to return
        - raw_result (bool): Return raw response
        - **kwargs: Same options as get_query_result()
        
        Returns:
        QueryResult | dict: Partitioned query results
        """

Index Management

Create and manage indexes for query optimization.

class CouchDatabase(dict):
    """Index management methods."""
    
    def get_query_indexes(self, raw_result=False):
        """
        List all query indexes in the database.
        
        Parameters:
        - raw_result (bool): Return raw response
        
        Returns:
        list[dict] | dict: Index definitions or raw response
        """
    
    def create_query_index(self, design_document_id=None, index_name=None, index_type='json', partitioned=None, **kwargs):
        """
        Create a query index.
        
        Parameters:
        - design_document_id (str): Design document ID for index
        - index_name (str): Name for the index
        - index_type (str): Index type ('json', 'text', 'special')
        - partitioned (bool): Whether index is partitioned
        - fields (list[str | dict]): Fields to index
        - selector (dict): Partial filter selector for index
        
        Returns:
        dict: Index creation response
        
        Raises:
        CloudantIndexException: Index creation failed
        """
    
    def delete_query_index(self, design_document_id, index_type, index_name):
        """
        Delete a query index.
        
        Parameters:
        - design_document_id (str): Design document containing index
        - index_type (str): Type of index to delete
        - index_name (str): Name of index to delete
        
        Returns:
        dict: Deletion response
        
        Raises:
        CloudantIndexException: Index deletion failed
        """

Index Classes

Object-oriented index management.

class Index:
    """
    JSON query index management.
    """
    
    def __init__(self, database, design_document_id=None, name=None, partitioned=None, **kwargs):
        """
        Initialize index instance.
        
        Parameters:
        - database (CloudantDatabase): Target database
        - design_document_id (str): Design document ID
        - name (str): Index name
        - partitioned (bool): Partitioned index flag
        - fields (list[str | dict]): Fields to index
        - selector (dict): Partial filter selector
        """
    
    def create(self):
        """
        Create index in database.
        
        Returns:
        dict: Creation response
        
        Raises:
        CloudantIndexException: Creation failed
        """
    
    def delete(self):
        """
        Delete index from database.
        
        Returns:
        dict: Deletion response
        
        Raises:
        CloudantIndexException: Deletion failed
        """
    
    @property
    def index_url(self):
        """Index URL endpoint"""
        
    @property
    def design_document_id(self):
        """Design document ID containing index"""
        
    @property
    def name(self):
        """Index name"""
        
    @property
    def type(self):
        """Index type ('json', 'text', 'special')"""

class TextIndex(Index):
    """
    Text search index for full-text search capabilities.
    """

class SpecialIndex(Index):
    """
    Special index for built-in indexes like _all_docs.
    """

Result Collections

Sliceable, key-accessible, and iterable result collections for efficient data access and pagination.

class Result:
    """
    Key accessible, sliceable, and iterable interface to result collections.
    
    Supports efficient paged iteration and flexible data access patterns
    including index-based access, key-based access, and slicing.
    """
    
    def __init__(self, method_ref, **options):
        """
        Initialize result collection.
        
        Parameters:
        - method_ref: Callable that returns JSON result data
        - descending (bool): Return documents in descending key order
        - endkey: Stop returning records at specified key
        - endkey_docid (str): Stop at specified document ID
        - group (bool): Group reduce results
        - group_level (int): Group level for complex keys
        - include_docs (bool): Include full document content
        - inclusive_end (bool): Include rows with endkey
        - key: Return only documents matching specified key
        - keys (list): Return only documents matching specified keys
        - limit (int): Maximum number of results
        - page_size (int): Page size for iteration (default: 100)
        - reduce (bool): Use reduce function
        - skip (int): Skip specified number of rows
        - stable (bool): Use stable set of shards
        - stale (str): Allow stale results ('ok' or 'update_after')
        - startkey: Start returning records from specified key
        - startkey_docid (str): Start from specified document ID
        - update (str): Update view before/after response ('true', 'false', 'lazy')
        """
    
    def __getitem__(self, arg):
        """
        Key access and slicing support.
        
        Parameters:
        - arg (int): Index access - skip N records, get next
        - arg (str | list | ResultByKey): Key access - get records matching key
        - arg (slice): Slice access - get range of records
        
        Returns:
        list: Rows data in JSON format
        """
    
    def __iter__(self):
        """
        Iterate over result collection with automatic pagination.
        
        Yields:
        dict: Individual result documents
        """
    
    def all(self):
        """
        Retrieve all results as a list.
        
        Returns:
        list: All result documents
        """

class ResultByKey:
    """
    Wrapper for values used to retrieve records by document key.
    
    Distinguishes between index access and key access when key is numeric.
    """
    
    def __init__(self, value):
        """
        Initialize key wrapper.
        
        Parameters:
        - value: The key value to match against
        """
    
    def __call__(self):
        """
        Get the wrapped key value.
        
        Returns:
        The original key value
        """

class QueryResult(Result):
    """
    Specialized result collection for Cloudant Query results.
    
    Extends Result with query-specific iteration using bookmarks
    and index-only access patterns.
    """
    
    def __init__(self, query, **options):
        """
        Initialize query result collection.
        
        Parameters:
        - query: Query callable reference
        - bookmark (str): Pagination bookmark
        - fields (list[str]): Fields to return
        - page_size (int): Page size for iteration (default: 100)
        - r (int): Read quorum for results
        - selector (dict): Query selector criteria
        - sort (list): Sort specification
        - use_index (str): Specific index to use
        """
    
    def __getitem__(self, arg):
        """
        Index-only access and slicing for query results.
        
        Parameters:
        - arg (int): Index access only
        - arg (slice): Index slice only (no key-based slicing)
        
        Returns:
        list: Document data in JSON format
        
        Raises:
        ResultException: If key-based access attempted
        """

Search Capabilities (Cloudant)

Full-text search using Lucene indexes.

class CloudantDatabase(CouchDatabase):
    """Search methods."""
    
    def get_search_result(self, ddoc_id, index_name, **query_params):
        """
        Execute full-text search query.
        
        Parameters:
        - ddoc_id (str): Design document ID containing search index
        - index_name (str): Search index name
        - q (str): Lucene query string
        - bookmark (str): Pagination bookmark
        - limit (int): Maximum results
        - sort (str | list): Sort specification
        - include_docs (bool): Include document content
        - include_fields (list[str]): Specific fields to include
        - ranges (dict): Numeric range facets
        - counts (list[str]): String facet counts
        - drilldown (list[list]): Facet drill-down
        - group_field (str): Group results by field
        - group_limit (int): Results per group
        - group_sort (str | list): Sort within groups
        
        Returns:
        dict: Search results with hits, facets, and metadata
        
        Raises:
        CloudantDatabaseException: Search failed
        """
    
    def get_partitioned_search_result(self, partition_key, ddoc_id, index_name, **query_params):
        """
        Execute search within specific partition.
        
        Parameters:
        - partition_key (str): Partition identifier
        - ddoc_id (str): Design document ID
        - index_name (str): Search index name
        - **query_params: Same options as get_search_result()
        
        Returns:
        dict: Partitioned search results
        """

Usage Examples

Basic Queries

from cloudant import cloudant

with cloudant('user', 'pass', account='myaccount') as client:
    db = client['my_database']
    
    # Simple equality query
    selector = {'type': 'user', 'status': 'active'}
    result = db.get_query_result(selector)
    
    for doc in result:
        print(f"Active user: {doc['name']}")
    
    # Query with specific fields
    fields = ['_id', 'name', 'email']
    result = db.get_query_result(selector, fields=fields)
    
    for doc in result:
        print(f"User: {doc['name']} ({doc['email']})")

Complex Queries

from cloudant import cloudant

with cloudant('user', 'pass', account='myaccount') as client:
    db = client['my_database']
    
    # Range and comparison operators
    selector = {
        'type': 'order',
        'total': {'$gt': 100, '$lt': 1000},
        'status': {'$in': ['pending', 'processing']},
        'created_date': {'$gte': '2023-01-01'}
    }
    
    # Sort by total descending, then by date ascending
    sort = [{'total': 'desc'}, {'created_date': 'asc'}]
    
    result = db.get_query_result(
        selector=selector,
        sort=sort,
        limit=50,
        fields=['_id', 'total', 'status', 'created_date']
    )
    
    for doc in result:
        print(f"Order {doc['_id']}: ${doc['total']} - {doc['status']}")
    
    # Text search with regex
    selector = {
        'name': {'$regex': '(?i)john.*'},  # Case-insensitive regex
        'tags': {'$all': ['developer', 'python']}
    }
    
    result = db.get_query_result(selector)

Query Object Usage

from cloudant import cloudant
from cloudant.query import Query

with cloudant('user', 'pass', account='myaccount') as client:
    db = client['my_database']
    
    # Create reusable query
    user_query = Query(
        db,
        selector={'type': 'user'},
        fields=['_id', 'name', 'email', 'created_date'],
        sort=[{'created_date': 'desc'}]
    )
    
    # Execute with default parameters
    recent_users = user_query()
    for user in recent_users:
        print(f"User: {user['name']}")
    
    # Execute with parameter overrides
    active_users = user_query(
        selector={'type': 'user', 'status': 'active'},
        limit=10
    )
    
    for user in active_users:
        print(f"Active user: {user['name']}")

Index Management

from cloudant import cloudant
from cloudant.index import Index, TextIndex

with cloudant('user', 'pass', account='myaccount') as client:
    db = client['my_database']
    
    # List existing indexes
    indexes = db.get_query_indexes()
    for idx in indexes['indexes']:
        print(f"Index: {idx['name']} on {idx['def']['fields']}")
    
    # Create JSON index
    db.create_query_index(
        fields=['type', 'status', 'created_date'],
        index_name='type_status_date_idx'
    )
    
    # Create partial index with selector
    db.create_query_index(
        fields=['email'],
        index_name='user_email_idx',
        selector={'type': 'user'}  # Only index user documents
    )
    
    # Using Index class
    user_index = Index(
        db,
        name='user_search_idx',
        fields=['name', 'email', {'created_date': 'desc'}]
    )
    user_index.create()
    
    # Create text search index
    search_index = TextIndex(
        db,
        name='content_search',
        fields=[
            {'name': 'title', 'type': 'string'},
            {'name': 'content', 'type': 'string'},
            {'name': 'tags', 'type': 'string'}
        ]
    )
    search_index.create()
    
    # Delete index
    db.delete_query_index('_design/user_search_idx', 'json', 'user_search_idx')

Pagination

from cloudant import cloudant

with cloudant('user', 'pass', account='myaccount') as client:
    db = client['my_database']
    
    selector = {'type': 'product'}
    limit = 25
    bookmark = None
    page = 1
    
    while True:
        result = db.get_query_result(
            selector=selector,
            limit=limit,
            bookmark=bookmark,
            sort=[{'name': 'asc'}]
        )
        
        docs = list(result)
        if not docs:
            break
            
        print(f"Page {page}: {len(docs)} products")
        for doc in docs:
            print(f"  - {doc['name']}")
        
        # Get bookmark for next page
        if hasattr(result, 'bookmark'):
            bookmark = result.bookmark
            if not bookmark:  # No more pages
                break
        else:
            break
            
        page += 1

Text Search (Cloudant)

from cloudant import cloudant

with cloudant('user', 'pass', account='myaccount') as client:
    db = client['my_database']
    
    # Simple text search
    search_result = db.get_search_result(
        'content_ddoc',
        'content_search',
        q='python AND database',
        limit=20,
        include_docs=True
    )
    
    print(f"Found {search_result['total_rows']} matches")
    for hit in search_result['rows']:
        doc = hit['doc']
        print(f"Match: {doc['title']} (score: {hit['order'][0]})")
    
    # Advanced search with facets
    search_result = db.get_search_result(
        'content_ddoc',
        'content_search',
        q='*:*',  # Match all documents
        counts=['category', 'author'],  # Facet counts
        ranges={'price': {'low': '[0 TO 50]', 'high': '[50 TO *]'}},
        drilldown=[['category', 'electronics']],  # Filter by category
        group_field='author',
        group_limit=3
    )
    
    # Display facets
    for facet_name, counts in search_result.get('counts', {}).items():
        print(f"{facet_name} facets:")
        for value, count in counts.items():
            print(f"  {value}: {count}")

Partitioned Queries (Cloudant)

from cloudant import cloudant

with cloudant('user', 'pass', account='myaccount') as client:
    # Use partitioned database
    db = client['partitioned_database']
    
    # Query within specific partition
    result = db.get_partitioned_query_result(
        'user123',
        selector={'type': 'activity'},
        sort=[{'timestamp': 'desc'}],
        limit=10
    )
    
    for activity in result:
        print(f"Activity: {activity['action']} at {activity['timestamp']}")
    
    # Search within partition
    search_result = db.get_partitioned_search_result(
        'user123',
        'activity_ddoc',
        'activity_search',
        q='login OR logout',
        include_docs=True
    )

Result Collections Usage

from cloudant import cloudant
from cloudant.result import Result, ResultByKey

with cloudant('user', 'pass', account='myaccount') as client:
    db = client['my_database']
    
    # Create result collection from view
    result = Result(db.all_docs, include_docs=True)
    
    # Index-based access
    first_doc = result[0]  # Skip 0, get 1st document
    tenth_doc = result[9]  # Skip 9, get 10th document
    
    # Key-based access
    specific_doc = result['doc_key_123']  # Get documents with key 'doc_key_123'
    numeric_key = result[ResultByKey(42)]  # Get documents with numeric key 42
    
    # Slicing
    first_ten = result[0:10]  # First 10 documents
    next_batch = result[10:20]  # Documents 11-20
    all_after_100 = result[100:]  # All documents after 100th
    key_range = result['aaa':'zzz']  # Documents with keys between 'aaa' and 'zzz'
    
    # Iteration with automatic pagination
    for doc in result:
        print(f"Document: {doc['_id']}")
        if doc.get('_id') == 'stop_here':
            break
    
    # Get all results at once
    all_docs = result.all()
    print(f"Total documents: {len(all_docs)}")
    
    # Custom page size for iteration
    large_result = Result(db.all_docs, page_size=1000, include_docs=True)
    for doc in large_result:
        process_document(doc)

Query Result Collections

from cloudant import cloudant
from cloudant.query import Query
from cloudant.result import QueryResult

with cloudant('user', 'pass', account='myaccount') as client:
    db = client['my_database']
    
    # Create query result collection
    query = Query(db, selector={'type': 'user'})
    query_result = QueryResult(query, page_size=50)
    
    # Index-based access only (no key-based access for queries)
    first_user = query_result[0]
    users_10_to_20 = query_result[10:20]
    
    # Iteration with bookmark pagination
    for user in query_result:
        print(f"User: {user['name']}")
    
    # Custom query result with sort
    sorted_result = QueryResult(
        query,
        sort=[{'created_date': 'desc'}],
        fields=['_id', 'name', 'email']
    )
    
    recent_users = sorted_result[0:10]  # 10 most recent users

Advanced Result Patterns

from cloudant import cloudant
from cloudant.result import Result, ResultByKey

with cloudant('user', 'pass', account='myaccount') as client:
    db = client['my_database']
    
    # Complex key access (for views with complex keys)
    view_result = Result(db['_design/stats']['by_date_and_type'])
    
    # Access by complex key
    today_users = view_result[['2023-12-01', 'user']]
    date_range = view_result[['2023-12-01']:['2023-12-31']]
    
    # Numeric key handling
    numeric_result = Result(db['_design/counters']['by_id'])
    doc_by_id = numeric_result[ResultByKey(12345)]  # Key access, not index
    twelfth_doc = numeric_result[11]  # Index access (12th document)
    
    # Conditional iteration
    filtered_result = Result(
        db.all_docs,
        startkey='prefix_',
        endkey='prefix_\ufff0',  # All keys starting with 'prefix_'
        include_docs=True
    )
    
    for doc in filtered_result:
        if doc['doc']['status'] == 'active':
            print(f"Active document: {doc['id']}")
    
    # Reduce view results
    stats_result = Result(
        db['_design/analytics']['monthly_stats'],
        group=True,
        group_level=2
    )
    
    for stat in stats_result:
        month = stat['key']
        value = stat['value'] 
        print(f"Month {month}: {value} events")

Query Performance Optimization

from cloudant import cloudant

with cloudant('user', 'pass', account='myaccount') as client:
    db = client['my_database']
    
    # Force use of specific index
    result = db.get_query_result(
        selector={'type': 'user', 'status': 'active'},
        use_index='user_status_idx',
        execution_stats=True
    )
    
    # Check execution statistics
    if hasattr(result, 'execution_stats'):
        stats = result.execution_stats
        print(f"Execution time: {stats.get('execution_time_ms')}ms")
        print(f"Results examined: {stats.get('results_returned')}")
        print(f"Documents examined: {stats.get('total_docs_examined')}")
        print(f"Index used: {stats.get('index', {}).get('name')}")
    
    # Query with hint for index selection
    result = db.get_query_result(
        selector={'category': 'electronics', 'price': {'$lt': 500}},
        use_index=['category', 'price'],  # Compound index
        sort=[{'price': 'asc'}]
    )

Error Handling

Query and indexing operations can raise specific exceptions:

from cloudant import cloudant
from cloudant.error import CloudantDatabaseException, CloudantIndexException

with cloudant('user', 'pass', account='myaccount') as client:
    db = client['my_database']
    
    try:
        # Query with invalid selector
        result = db.get_query_result({'invalid_operator': {'$invalid': 'value'}})
    except CloudantDatabaseException as e:
        print(f"Query failed: {e}")
    
    try:
        # Create duplicate index
        db.create_query_index(fields=['email'], index_name='existing_index')
    except CloudantIndexException as e:
        print(f"Index creation failed: {e}")
    
    try:
        # Delete non-existent index
        db.delete_query_index('_design/missing', 'json', 'missing_index')
    except CloudantIndexException as e:
        print(f"Index deletion failed: {e}")

Install with Tessl CLI

npx tessl i tessl/pypi-cloudant

docs

authentication.md

change-feeds.md

database-management.md

document-operations.md

error-handling.md

http-adapters.md

index.md

query-indexing.md

replication.md

scheduler-monitoring.md

security-document.md

views-design-documents.md

tile.json