Advanced Search Filters for Classroom Management

Implementing Flexible Search Capabilities for Classroom Data

Understanding Advanced Search Requirements

Imagine you're a school administrator trying to find classrooms that match specific criteria. You might need to find all classrooms with "Mr." in the name, or all classrooms that can accommodate between 25-30 students. These are the kinds of flexible search capabilities we'll implement in this phase.

Key Search Features

We'll implement two main types of searches:

1. Pattern matching for classroom names (like finding all "Mr." classrooms)

2. Numeric range searches for student limits (like finding rooms that fit 20-30 students)

Implementing Name Pattern Matching

Let's start with implementing the classroom name search. This is similar to how you might search for a contact in your phone - partial matches should work.

Name Search Implementation

const { Op } = require('sequelize');

const getClassrooms = async (req, res) => {
    try {
        const { name } = req.query;
        const whereClause = {};
        
        // Add name filter if provided
        if (name) {
            whereClause.name = {
                [Op.like]: `%${name}%`
            };
        }
        
        const classrooms = await Classroom.findAll({
            where: whereClause,
            order: [['name', 'ASC']]
        });
        
        res.json(classrooms);
    } catch (error) {
        console.error('Error in classroom search:', error);
        res.status(500).json({
            error: 'Failed to search classrooms'
        });
    }
};

The '%' wildcards in SQL LIKE queries work similarly to how we might search a phonebook:

- '%mr%' would match "Mr. Smith", "Mrs. Jones", "Mr. Anderson"

- 'mr.%' would only match "Mr. Smith", "Mr. Anderson"

- '%room%' would match "Classroom 101", "Room A", "Homeroom"

Implementing Student Limit Range Search

Now let's implement the ability to search for classrooms based on their student capacity. This is more complex because we need to handle both exact matches and ranges.

Student Limit Search Implementation

const handleStudentLimitFilter = (studentLimit) => {
    if (!studentLimit) return null;
    
    // Check if it's a range query (contains comma)
    if (studentLimit.includes(',')) {
        const [min, max] = studentLimit.split(',').map(Number);
        
        // Validate the range values
        if (isNaN(min) || isNaN(max)) {
            throw new Error('Student Limit should be two numbers: min,max');
        }
        
        if (min > max) {
            throw new Error('Minimum limit cannot be greater than maximum limit');
        }
        
        return {
            [Op.between]: [min, max]
        };
    }
    
    // Handle exact match
    const limit = Number(studentLimit);
    if (isNaN(limit)) {
        throw new Error('Student Limit should be an integer');
    }
    
    return limit;
};

const getClassroomsWithFilters = async (req, res) => {
    try {
        const { name, studentLimit } = req.query;
        const whereClause = {};
        
        // Add name filter if provided
        if (name) {
            whereClause.name = {
                [Op.like]: `%${name}%`
            };
        }
        
        // Add student limit filter if provided
        if (studentLimit) {
            try {
                const limitFilter = handleStudentLimitFilter(studentLimit);
                if (limitFilter) {
                    whereClause.studentLimit = limitFilter;
                }
            } catch (error) {
                return res.status(400).json({
                    errors: [{ message: error.message }],
                    count: 0,
                    pageCount: 0
                });
            }
        }
        
        const classrooms = await Classroom.findAll({
            where: whereClause,
            order: [['name', 'ASC']]
        });
        
        res.json(classrooms);
    } catch (error) {
        console.error('Error in classroom search:', error);
        res.status(500).json({
            error: 'Failed to search classrooms'
        });
    }
};

Handling Complex Search Scenarios

Let's look at how our implementation handles different search scenarios:

Scenario 1: Simple Name Search

GET /classrooms?name=mr

This will find all classrooms with "mr" in their name, case-insensitive.

Scenario 2: Exact Student Limit

GET /classrooms?studentLimit=25

This will find classrooms that can hold exactly 25 students.

Scenario 3: Student Limit Range

GET /classrooms?studentLimit=20,30

This will find classrooms that can hold between 20 and 30 students.

Scenario 4: Combined Search

GET /classrooms?name=mr&studentLimit=20,30

This will find classrooms with "mr" in the name that can hold between 20 and 30 students.

Error Handling and Edge Cases

Proper error handling is crucial for a robust search system. Let's look at how we handle various edge cases:

Comprehensive Error Handling

const validateSearchParams = (params) => {
    const errors = [];
    
    if (params.studentLimit) {
        if (params.studentLimit.includes(',')) {
            const [min, max] = params.studentLimit.split(',').map(Number);
            if (isNaN(min) || isNaN(max)) {
                errors.push('Student Limit should be two numbers: min,max');
            } else if (min > max) {
                errors.push('Minimum limit cannot be greater than maximum limit');
            }
        } else {
            const limit = Number(params.studentLimit);
            if (isNaN(limit)) {
                errors.push('Student Limit should be an integer');
            }
        }
    }
    
    return errors;
};

Best Practices and Performance Considerations

Optimization Tips

When implementing classroom searches, consider these optimization strategies:

1. Add database indexes on frequently searched columns (name, studentLimit)

2. Use query parameter validation to prevent unnecessary database queries

3. Consider implementing result caching for common searches

4. Use parameterized queries to prevent SQL injection

Practical Applications

This search functionality enables several important administrative tasks:

1. Finding available classrooms for a specific class size

2. Locating all classrooms assigned to a specific teacher

3. Identifying classrooms that might need capacity adjustments

4. Planning classroom assignments for the next semester

Exercise: Extended Search Features

Try implementing these additional search features:

1. Search by floor number or building wing

2. Filter by classrooms that are currently under or over capacity

3. Search by available resources (whiteboard, projector, etc.)