MediaWiki:CRT Search.js: Difference between revisions
No edit summary |
No edit summary |
||
| Line 138: | Line 138: | ||
subobjectQuery: true, | subobjectQuery: true, | ||
subobjectProperty: 'Has mod type', | subobjectProperty: 'Has mod type', | ||
subobjectValue: 'RGB' | subobjectValue: 'RGB', | ||
subobjectExtraCondition: '[[Has mod feasible::Yes]]' | |||
}, | }, | ||
has_svideo_mod: { | has_svideo_mod: { | ||
| Line 145: | Line 146: | ||
subobjectQuery: true, | subobjectQuery: true, | ||
subobjectProperty: 'Has mod type', | subobjectProperty: 'Has mod type', | ||
subobjectValue: 'S-video' | subobjectValue: 'S-video', | ||
subobjectExtraCondition: '[[Has mod feasible::Yes]]' | |||
} | } | ||
} | } | ||
| Line 829: | Line 831: | ||
subobjectConditions.push({ | subobjectConditions.push({ | ||
property: filter.subobjectProperty, | property: filter.subobjectProperty, | ||
value: filter.subobjectValue | value: filter.subobjectValue, | ||
extraCondition: filter.subobjectExtraCondition || '' | |||
}); | }); | ||
} | } | ||
| Line 836: | Line 839: | ||
subobjectConditions.push({ | subobjectConditions.push({ | ||
property: filter.subobjectProperty, | property: filter.subobjectProperty, | ||
value: v | value: v, | ||
extraCondition: filter.subobjectExtraCondition || '' | |||
}); | }); | ||
}); | }); | ||
| Line 963: | Line 967: | ||
var subQueries = []; | var subQueries = []; | ||
subConditions.forEach(function(cond) { | subConditions.forEach(function(cond) { | ||
var subQuery = '[[' + cond.property + '::' + cond.value + ']]|?Has CRT model|limit=5000|format=json'; | // Build query with main condition and any extra conditions (like feasibility) | ||
var subQuery = '[[' + cond.property + '::' + cond.value + ']]'; | |||
if (cond.extraCondition) { | |||
subQuery += cond.extraCondition; | |||
} | |||
subQuery += '|?Has CRT model|limit=5000|format=json'; | |||
subQueries.push(subQuery); | subQueries.push(subQuery); | ||
console.log('Subobject query:', subQuery); | |||
}); | }); | ||
| Line 981: | Line 991: | ||
var isFirst = true; | var isFirst = true; | ||
results.forEach(function(data) { | results.forEach(function(data, queryIndex) { | ||
console.log('Subobject query', queryIndex, 'response:', data); | |||
// Check for SMW errors | |||
if (data.error) { | |||
console.error('Subobject query', queryIndex, 'error:', data.error); | |||
return; | |||
} | |||
var currentMatches = new Set(); | var currentMatches = new Set(); | ||
if (data.query && data.query.results) { | if (data.query && data.query.results) { | ||
var resultCount = Object.keys(data.query.results).length; | |||
console.log('Subobject query', queryIndex, 'found', resultCount, 'subobjects'); | |||
Object.values(data.query.results).forEach(function(result) { | Object.values(data.query.results).forEach(function(result) { | ||
if (result.printouts && result.printouts['Has CRT model']) { | if (result.printouts && result.printouts['Has CRT model']) { | ||
| Line 992: | Line 1,013: | ||
} | } | ||
}); | }); | ||
console.log('Subobject query', queryIndex, 'matched', currentMatches.size, 'CRT models'); | |||
} | } | ||
| Line 1,004: | Line 1,026: | ||
} | } | ||
}); | }); | ||
console.log('Total matching models after intersection:', matchingModels.size); | |||
if (matchingModels.size === 0) { | if (matchingModels.size === 0) { | ||
| Line 1,036: | Line 1,060: | ||
function fetchModelDetailsBatched(allModels, mainConditions, sortProperty) { | function fetchModelDetailsBatched(allModels, mainConditions, sortProperty) { | ||
var api = new mw.Api(); | var api = new mw.Api(); | ||
console.log('fetchModelDetailsBatched: Total models:', allModels.length, 'Offset:', currentOffset); | |||
// Get just the models for the current page | // Get just the models for the current page | ||
| Line 1,045: | Line 1,071: | ||
return; | return; | ||
} | } | ||
console.log('fetchModelDetailsBatched: Page models:', pageModels.length); | |||
// Split into small batches to avoid SMW query size limits | // Split into small batches to avoid SMW query size limits | ||
// Use | // Use 15 models per batch to stay well under limits | ||
var BATCH_SIZE = | var BATCH_SIZE = 15; | ||
var batches = []; | var batches = []; | ||
for (var i = 0; i < pageModels.length; i += BATCH_SIZE) { | for (var i = 0; i < pageModels.length; i += BATCH_SIZE) { | ||
batches.push(pageModels.slice(i, i + BATCH_SIZE)); | batches.push(pageModels.slice(i, i + BATCH_SIZE)); | ||
} | } | ||
console.log('fetchModelDetailsBatched: Batches:', batches.length); | |||
// Build and execute batched queries | // Build and execute batched queries | ||
var batchPromises = batches.map(function(batch) { | var batchPromises = batches.map(function(batch, batchIndex) { | ||
// Use disjunction with || instead of separate [[]] OR [[]] to reduce query depth | // Use disjunction with || instead of separate [[]] OR [[]] to reduce query depth | ||
var disjunction = batch.join('||'); | var disjunction = batch.join('||'); | ||
| Line 1,064: | Line 1,094: | ||
query = '[[Category:CRT models]]' + mainConditions + query; | query = '[[Category:CRT models]]' + mainConditions + query; | ||
} | } | ||
var fullQuery = query + | |||
'|?Has image#100px=image' + | |||
'|?Has brand=brand' + | |||
'|?Has model code=model' + | |||
'|?Has CRT type=type' + | |||
'|?Has screen size inches=size' + | |||
'|?Has aspect ratio=aspect' + | |||
'|?Has TVL=tvl' + | |||
'|limit=50' + | |||
'|format=json'; | |||
console.log('Batch', batchIndex, 'query:', fullQuery.substring(0, 200) + '...'); | |||
return api.get({ | return api.get({ | ||
action: 'ask', | action: 'ask', | ||
query: | query: fullQuery, | ||
format: 'json' | format: 'json' | ||
}); | }); | ||
| Line 1,084: | Line 1,118: | ||
// Merge results from all batches | // Merge results from all batches | ||
var mergedResults = {}; | var mergedResults = {}; | ||
batchResults.forEach(function(data) { | var hasErrors = false; | ||
batchResults.forEach(function(data, index) { | |||
console.log('Batch', index, 'response:', data); | |||
// Check for SMW errors in the response | |||
if (data.error) { | |||
console.error('Batch', index, 'SMW error:', data.error); | |||
hasErrors = true; | |||
return; | |||
} | |||
if (data.query && data.query.results) { | if (data.query && data.query.results) { | ||
var resultCount = Object.keys(data.query.results).length; | |||
console.log('Batch', index, 'returned', resultCount, 'results'); | |||
Object.assign(mergedResults, data.query.results); | Object.assign(mergedResults, data.query.results); | ||
} else { | |||
console.warn('Batch', index, 'returned no results'); | |||
} | } | ||
}); | }); | ||
if (hasErrors && Object.keys(mergedResults).length === 0) { | |||
isLoading = false; | |||
showError('Search query too complex. Try fewer filters.'); | |||
return; | |||
} | |||
// Sort merged results by the specified property | // Sort merged results by the specified property | ||
| Line 1,101: | Line 1,156: | ||
sortedResults[key] = mergedResults[key]; | sortedResults[key] = mergedResults[key]; | ||
}); | }); | ||
console.log('Total merged results:', Object.keys(sortedResults).length); | |||
isLoading = false; | isLoading = false; | ||