mirror of
https://github.com/zotero/zotero.git
synced 2026-10-06 02:50:03 +00:00
Use one combined tag query for a multiple-row selection
This commit is contained in:
parent
2dae3615d9
commit
6bbcaba7ff
2 changed files with 40 additions and 3 deletions
|
|
@ -130,9 +130,12 @@ Zotero.TagSelector = class TagSelectorContainer extends React.PureComponent {
|
|||
*/
|
||||
async _safeGetTags(...args) {
|
||||
try {
|
||||
let tags = (await Promise.all(
|
||||
this.collectionTreeRows.map(row => row.getTags(...args))
|
||||
)).flat();
|
||||
let rows = this.collectionTreeRows || [];
|
||||
// A single row uses its own cached temp table directly; multiple rows are
|
||||
// combined into one temp table and query to avoid a per-row query
|
||||
let tags = rows.length == 1
|
||||
? await rows[0].getTags(...args)
|
||||
: await Zotero.CollectionTreeRow.getTagsAcrossRows(rows, ...args);
|
||||
// Multiple rows (collections, or collections across libraries) can return
|
||||
// the same tag, so dedupe by name
|
||||
return this._dedupeTags(tags);
|
||||
|
|
|
|||
|
|
@ -567,6 +567,40 @@ Zotero.CollectionTreeRow.prototype.getTags = async function (types, tagIDs) {
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns all the tags used by items across multiple rows' views
|
||||
*
|
||||
* Combines the rows' search results into a single temporary table and runs one tag
|
||||
* query, rather than creating a temp table and running a separate query per row.
|
||||
*
|
||||
* @param {Zotero.CollectionTreeRow[]} rows
|
||||
* @param {Number[]} [types]
|
||||
* @param {Number[]} [tagIDs]
|
||||
* @return {Promise<Object[]>}
|
||||
*/
|
||||
Zotero.CollectionTreeRow.getTagsAcrossRows = async function (rows, types, tagIDs) {
|
||||
// share/bucket/feeds rows never contribute tags (see getTags())
|
||||
var tagRows = rows.filter(row => !['share', 'bucket', 'feeds'].includes(row.type));
|
||||
if (!tagRows.length) {
|
||||
return [];
|
||||
}
|
||||
// Combine the rows' search results into a single set of item IDs
|
||||
var itemIDs = new Set();
|
||||
for (let ids of await Promise.all(tagRows.map(row => row.getSearchResults(false)))) {
|
||||
for (let id of ids) {
|
||||
itemIDs.add(id);
|
||||
}
|
||||
}
|
||||
var tmpTable = await Zotero.Search.idsToTempTable([...itemIDs]);
|
||||
try {
|
||||
return await Zotero.Tags.getAllWithin({ tmpTable, types, tagIDs });
|
||||
}
|
||||
finally {
|
||||
await Zotero.DB.queryAsync(`DROP TABLE IF EXISTS ${tmpTable}`, false, { noCache: true });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clear the per-instance search cache. Call this at the start of a refresh cycle
|
||||
* or when search/tag filters change, so the next getSearchResults()/getSearchObject()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue