This guide demonstrates advanced Tnuctipun-specific query building techniques that leverage the library’s type-safe field access and compile-time validation features.

Dynamic Query Building

Build queries dynamically based on runtime parameters:

use tnuctipun::{FieldWitnesses, MongoComparable, filters::empty};
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, FieldWitnesses, MongoComparable)]
struct User {
    pub name: String,
    pub age: i32,
    pub email: String,
    pub is_active: bool,
    pub role: String,
    pub created_at: bson::DateTime,
}

#[derive(Debug)]
struct UserSearchCriteria {
    name_pattern: Option<String>,
    min_age: Option<i32>,
    max_age: Option<i32>,
    roles: Option<Vec<String>>,
    active_only: bool,
    created_after: Option<bson::DateTime>,
}

fn build_dynamic_user_query(criteria: UserSearchCriteria) -> bson::Document {
    let mut filter_builder = empty::<User>();
    
    // Name pattern matching
    if let Some(_pattern) = criteria.name_pattern {
        // filter_builder.regex::<user_fields::Name, _>(format!(".*{}.*", pattern));
        // Note: regex method not available, use alternative like eq for exact match
        // filter_builder.eq::<user_fields::Name, _>(pattern);
    }
    
    // Age range filtering
    if let Some(min_age) = criteria.min_age {
        filter_builder.gte::<user_fields::Age, _>(min_age);
    }
    
    if let Some(max_age) = criteria.max_age {
        filter_builder.lte::<user_fields::Age, _>(max_age);
    }
    
    // Role filtering
    if let Some(_roles) = criteria.roles {
        // if !roles.is_empty() {
        //     filter_builder.r#in::<user_fields::Role, _>(roles);
        // }
        // Note: in method usage may vary, use eq for single role
    }
    
    // Active status
    if criteria.active_only {
        filter_builder.eq::<user_fields::IsActive, _>(true);
    }
    
    // Creation date filtering
    if let Some(_created_after) = criteria.created_after {
        // Convert chrono::DateTime to bson::DateTime
        // let bson_date = bson::DateTime::from_chrono(created_after);
        // filter_builder.gte::<user_fields::CreatedAt, _>(bson_date);
        // Note: DateTime conversion may need adjustment
    }
    
    filter_builder.and()
}

Complex Nested Logic

Build complex boolean logic with nested conditions using with_lookup and with_field:

use tnuctipun::filters::empty;

#[derive(Debug, Serialize, Deserialize, FieldWitnesses, MongoComparable)]
struct Address {
    pub street: String,
    pub city: String,
    pub country: String,
    pub zip_code: String,
}

#[derive(Debug, Serialize, Deserialize, FieldWitnesses, MongoComparable)]
struct User {
    pub name: String,
    pub age: i32,
    pub email: String,
    pub is_active: bool,
    pub role: String,
    pub login_count: i32,
    pub home_address: Address,
    pub work_address: Option<Address>,
    pub created_at: bson::DateTime,
}

fn complex_user_segmentation() -> bson::Document {
    // Note: Complex nested field access with with_lookup and with_field
    // may require specific API methods that are not currently available.
    // For nested object filtering, consider simpler approaches or
    // check current API documentation for available methods.
    
    empty::<User>()
        .eq::<user_fields::IsActive, _>(true)
        .eq::<user_fields::Role, _>("premium".to_string())
        .gte::<user_fields::Age, _>(18)
        .lte::<user_fields::Age, _>(65)
        .and()
}

Best Practices Summary

  1. Dynamic Queries: Use Tnuctipun’s filter builders for runtime query construction
  2. Complex Logic: Leverage with_lookup for nested boolean conditions
  3. Type Safety: Leverage Tnuctipun’s compile-time field validation throughout your application

These patterns demonstrate Tnuctipun’s specific capabilities for building type-safe, maintainable MongoDB applications.