MediaWiki:CRT Search.js: Difference between revisions

No edit summary
No edit summary
Line 948: Line 948:
     * Perform search with subobject conditions (inputs/mods)
     * Perform search with subobject conditions (inputs/mods)
     * This requires a two-step query due to SMW limitations
     * This requires a two-step query due to SMW limitations
    *
    * Strategy: Get all matching model names first, then paginate client-side
    * to avoid hitting SMW's query size/depth limits with huge OR queries
    */
    /**
    * Perform search with subobject conditions (inputs/mods)
    * Uses batched queries to avoid SMW query size limits
     */
     */
     function performSubobjectSearch(queryData, sortProperty) {
     function performSubobjectSearch(queryData, sortProperty) {
Line 953: Line 960:
         var subConditions = queryData.subobjectConditions;
         var subConditions = queryData.subobjectConditions;
          
          
         // Build a query that finds pages through their subobjects
         // Build queries to find pages through their subobjects
         var subQueries = [];
         var subQueries = [];
         subConditions.forEach(function(cond) {
         subConditions.forEach(function(cond) {
Line 1,005: Line 1,012:
             }
             }
              
              
            // Now query for those specific models with main conditions
             var matchingModelsArray = Array.from(matchingModels).sort();
             var modelConditions = Array.from(matchingModels).map(function(m) {
            totalResults = matchingModelsArray.length;
                return '[[' + m + ']]';
           
             });
            // Check if we have additional main conditions beyond just Category:CRT models
            var mainConditions = queryData.mainQuery.replace('[[Category:CRT models]]', '').trim();
              
            // Fetch details for the matching models using batched queries
            fetchModelDetailsBatched(matchingModelsArray, mainConditions, sortProperty);
              
              
             // Combine with main query conditions (remove category since we're targeting specific pages)
        }).catch(function(error) {
             var mainConditions = queryData.mainQuery.replace('[[Category:CRT models]]', '');
            isLoading = false;
             var combinedQuery = '(' + modelConditions.join(' OR ') + ')' + mainConditions;
             showError('Search failed. Please try again.');
            console.error('Subobject query error:', error);
        });
    }
   
    /**
    * Fetch model details using batched queries to avoid SMW size limits
    * @param {Array} allModels - All matching model names
    * @param {string} mainConditions - Additional SMW conditions (empty string if none)
    * @param {string} sortProperty - Property to sort by
    */
    function fetchModelDetailsBatched(allModels, mainConditions, sortProperty) {
        var api = new mw.Api();
       
        // Get just the models for the current page
        var pageModels = allModels.slice(currentOffset, currentOffset + RESULTS_PER_PAGE);
       
        if (pageModels.length === 0) {
            isLoading = false;
            displayResults({ query: { results: {} } });
            return;
        }
       
        // Split into small batches to avoid SMW query size limits
        // Use 25 models per batch to stay well under limits
        var BATCH_SIZE = 25;
        var batches = [];
        for (var i = 0; i < pageModels.length; i += BATCH_SIZE) {
             batches.push(pageModels.slice(i, i + BATCH_SIZE));
        }
       
        // Build and execute batched queries
        var batchPromises = batches.map(function(batch) {
            // Use disjunction with || instead of separate [[]] OR [[]] to reduce query depth
            var disjunction = batch.join('||');
             var query = '[[' + disjunction + ']]';
              
              
             totalResults = matchingModels.size;
             // Add main conditions if present
            if (mainConditions) {
                query = '[[Category:CRT models]]' + mainConditions + query;
            }
              
              
             // Get paginated results
             return api.get({
            api.get({
                 action: 'ask',
                 action: 'ask',
                 query: combinedQuery +  
                 query: query +
                     '|?Has image#100px=image' +
                     '|?Has image#100px=image' +
                     '|?Has brand=brand' +
                     '|?Has brand=brand' +
Line 1,027: Line 1,075:
                     '|?Has aspect ratio=aspect' +
                     '|?Has aspect ratio=aspect' +
                     '|?Has TVL=tvl' +
                     '|?Has TVL=tvl' +
                    '|sort=' + sortProperty +
                     '|limit=50' +
                    '|order=asc' +
                     '|limit=' + RESULTS_PER_PAGE +
                    '|offset=' + currentOffset +
                     '|format=json',
                     '|format=json',
                 format: 'json'
                 format: 'json'
             }).done(function(data) {
             });
                isLoading = false;
        });
                 displayResults(data);
       
             }).fail(function(error) {
        Promise.all(batchPromises).then(function(batchResults) {
                 isLoading = false;
            // Merge results from all batches
                 showError('Search failed. Please try again.');
            var mergedResults = {};
                console.error('SMW combined query error:', error);
            batchResults.forEach(function(data) {
                 if (data.query && data.query.results) {
                    Object.assign(mergedResults, data.query.results);
                }
             });
           
            // Sort merged results by the specified property
            var sortedKeys = Object.keys(mergedResults).sort(function(a, b) {
                 var aVal = getSortValue(mergedResults[a], sortProperty);
                 var bVal = getSortValue(mergedResults[b], sortProperty);
                return aVal.localeCompare(bVal);
            });
           
            var sortedResults = {};
            sortedKeys.forEach(function(key) {
                sortedResults[key] = mergedResults[key];
             });
             });
              
              
            isLoading = false;
            displayResults({ query: { results: sortedResults } });
         }).catch(function(error) {
         }).catch(function(error) {
             isLoading = false;
             isLoading = false;
             showError('Search failed. Please try again.');
             showError('Search failed. Please try again.');
             console.error('Subobject query error:', error);
             console.error('Batch query error:', error);
         });
         });
    }
   
    /**
    * Get sort value from a result for client-side sorting
    */
    function getSortValue(result, sortProperty) {
        if (!result || !result.printouts) return '';
       
        var propMap = {
            'Has brand': 'brand',
            'Has model code': 'model',
            'Has screen size inches': 'size',
            'Has CRT type': 'type'
        };
       
        var key = propMap[sortProperty] || 'brand';
        var printout = result.printouts[key];
       
        if (!printout || !printout[0]) return '';
       
        var val = printout[0];
        if (typeof val === 'object') {
            return String(val.fulltext || val.value || '');
        }
        return String(val);
     }
     }


MediaWiki Appliance - Powered by TurnKey Linux