mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-11-04 07:01:31 +08:00 
			
		
		
		
	revert #980 because of performance issues
This commit is contained in:
		
							parent
							
								
									109bead1c7
								
							
						
					
					
						commit
						4c6e9480e4
					
				
							
								
								
									
										2
									
								
								.idea/dataSources.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								.idea/dataSources.xml
									
									
									
										generated
									
									
									
								
							@ -5,7 +5,7 @@
 | 
				
			|||||||
      <driver-ref>sqlite.xerial</driver-ref>
 | 
					      <driver-ref>sqlite.xerial</driver-ref>
 | 
				
			||||||
      <synchronize>true</synchronize>
 | 
					      <synchronize>true</synchronize>
 | 
				
			||||||
      <jdbc-driver>org.sqlite.JDBC</jdbc-driver>
 | 
					      <jdbc-driver>org.sqlite.JDBC</jdbc-driver>
 | 
				
			||||||
      <jdbc-url>jdbc:sqlite:$PROJECT_DIR$/../trilium-data/document.db</jdbc-url>
 | 
					      <jdbc-url>jdbc:sqlite:$USER_HOME$/trilium-data/document.db</jdbc-url>
 | 
				
			||||||
    </data-source>
 | 
					    </data-source>
 | 
				
			||||||
    <data-source source="LOCAL" name="document" uuid="066dc5f4-4097-429e-8cf1-3adc0a9d648a">
 | 
					    <data-source source="LOCAL" name="document" uuid="066dc5f4-4097-429e-8cf1-3adc0a9d648a">
 | 
				
			||||||
      <driver-ref>sqlite.xerial</driver-ref>
 | 
					      <driver-ref>sqlite.xerial</driver-ref>
 | 
				
			||||||
 | 
				
			|||||||
@ -12,9 +12,7 @@ const VIRTUAL_ATTRIBUTES = [
 | 
				
			|||||||
    "type",
 | 
					    "type",
 | 
				
			||||||
    "mime",
 | 
					    "mime",
 | 
				
			||||||
    "text",
 | 
					    "text",
 | 
				
			||||||
    "parentCount",
 | 
					    "parentCount"
 | 
				
			||||||
    "attributeName",
 | 
					 | 
				
			||||||
    "attributeValue"
 | 
					 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = function(filters, selectedColumns = 'notes.*') {
 | 
					module.exports = function(filters, selectedColumns = 'notes.*') {
 | 
				
			||||||
@ -35,29 +33,11 @@ module.exports = function(filters, selectedColumns = 'notes.*') {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            // forcing to use particular index since SQLite query planner would often choose something pretty bad
 | 
					            // forcing to use particular index since SQLite query planner would often choose something pretty bad
 | 
				
			||||||
            joins[alias] = `LEFT JOIN attributes AS ${alias} INDEXED BY IDX_attributes_noteId_index `
 | 
					            joins[alias] = `LEFT JOIN attributes AS ${alias} INDEXED BY IDX_attributes_noteId_index `
 | 
				
			||||||
                + `ON ${alias}.noteId = notes.noteId AND ${alias}.isDeleted = 0 `
 | 
					                + `ON ${alias}.noteId = notes.noteId `
 | 
				
			||||||
                + `AND ${alias}.name = '${property}' `;
 | 
					                + `AND ${alias}.name = '${property}' AND ${alias}.isDeleted = 0`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            accessor = `${alias}.value`;
 | 
					            accessor = `${alias}.value`;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (['attributeType', 'attributeName', 'attributeValue'].includes(property)) {
 | 
					 | 
				
			||||||
            const alias = "attr_filter";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (!(alias in joins)) {
 | 
					 | 
				
			||||||
                joins[alias] = `LEFT JOIN attributes AS ${alias} INDEXED BY IDX_attributes_noteId_index `
 | 
					 | 
				
			||||||
                    + `ON ${alias}.noteId = notes.noteId AND ${alias}.isDeleted = 0`;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (property === 'attributeType') {
 | 
					 | 
				
			||||||
                accessor = `${alias}.type`
 | 
					 | 
				
			||||||
            } else if (property === 'attributeName') {
 | 
					 | 
				
			||||||
                accessor = `${alias}.name`
 | 
					 | 
				
			||||||
            } else if (property === 'attributeValue') {
 | 
					 | 
				
			||||||
                accessor = `${alias}.value`
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                throw new Error(`Unrecognized property ${property}`);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else if (property === 'content') {
 | 
					        else if (property === 'content') {
 | 
				
			||||||
            const alias = "note_contents";
 | 
					            const alias = "note_contents";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -93,40 +73,33 @@ module.exports = function(filters, selectedColumns = 'notes.*') {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let where = '1';
 | 
				
			||||||
    const params = [];
 | 
					    const params = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function parseWhereFilters(filters) {
 | 
					 | 
				
			||||||
        let whereStmt = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for (const filter of filters) {
 | 
					        for (const filter of filters) {
 | 
				
			||||||
            if (['isarchived', 'in', 'orderby', 'limit'].includes(filter.name.toLowerCase())) {
 | 
					            if (['isarchived', 'in', 'orderby', 'limit'].includes(filter.name.toLowerCase())) {
 | 
				
			||||||
                continue; // these are not real filters
 | 
					                continue; // these are not real filters
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (whereStmt) {
 | 
					        where += " " + filter.relation + " ";
 | 
				
			||||||
                whereStmt += " " + filter.relation + " ";
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (filter.children) {
 | 
					 | 
				
			||||||
                whereStmt += "(" + parseWhereFilters(filter.children) + ")";
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const accessor = getAccessor(filter.name);
 | 
					            const accessor = getAccessor(filter.name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (filter.operator === 'exists') {
 | 
					            if (filter.operator === 'exists') {
 | 
				
			||||||
                whereStmt += `${accessor} IS NOT NULL`;
 | 
					            where += `${accessor} IS NOT NULL`;
 | 
				
			||||||
            } else if (filter.operator === 'not-exists') {
 | 
					        }
 | 
				
			||||||
                whereStmt += `${accessor} IS NULL`;
 | 
					        else if (filter.operator === 'not-exists') {
 | 
				
			||||||
            } else if (filter.operator === '=' || filter.operator === '!=') {
 | 
					            where += `${accessor} IS NULL`;
 | 
				
			||||||
                whereStmt += `${accessor} ${filter.operator} ?`;
 | 
					        }
 | 
				
			||||||
 | 
					        else if (filter.operator === '=' || filter.operator === '!=') {
 | 
				
			||||||
 | 
					            where += `${accessor} ${filter.operator} ?`;
 | 
				
			||||||
                params.push(filter.value);
 | 
					                params.push(filter.value);
 | 
				
			||||||
            } else if (filter.operator === '*=' || filter.operator === '!*=') {
 | 
					            } else if (filter.operator === '*=' || filter.operator === '!*=') {
 | 
				
			||||||
                whereStmt += `${accessor}`
 | 
					            where += `${accessor}`
 | 
				
			||||||
                    + (filter.operator.includes('!') ? ' NOT' : '')
 | 
					                    + (filter.operator.includes('!') ? ' NOT' : '')
 | 
				
			||||||
                    + ` LIKE ` + utils.prepareSqlForLike('%', filter.value, '');
 | 
					                    + ` LIKE ` + utils.prepareSqlForLike('%', filter.value, '');
 | 
				
			||||||
            } else if (filter.operator === '=*' || filter.operator === '!=*') {
 | 
					            } else if (filter.operator === '=*' || filter.operator === '!=*') {
 | 
				
			||||||
                whereStmt += `${accessor}`
 | 
					            where += `${accessor}`
 | 
				
			||||||
                    + (filter.operator.includes('!') ? ' NOT' : '')
 | 
					                    + (filter.operator.includes('!') ? ' NOT' : '')
 | 
				
			||||||
                    + ` LIKE ` + utils.prepareSqlForLike('', filter.value, '%');
 | 
					                    + ` LIKE ` + utils.prepareSqlForLike('', filter.value, '%');
 | 
				
			||||||
            } else if (filter.operator === '*=*' || filter.operator === '!*=*') {
 | 
					            } else if (filter.operator === '*=*' || filter.operator === '!*=*') {
 | 
				
			||||||
@ -145,8 +118,9 @@ module.exports = function(filters, selectedColumns = 'notes.*') {
 | 
				
			|||||||
                    condition = `(${condition} AND notes.isProtected = 0)`;
 | 
					                    condition = `(${condition} AND notes.isProtected = 0)`;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                whereStmt += condition;
 | 
					            where += condition;
 | 
				
			||||||
            } else if ([">", ">=", "<", "<="].includes(filter.operator)) {
 | 
					        }
 | 
				
			||||||
 | 
					        else if ([">", ">=", "<", "<="].includes(filter.operator)) {
 | 
				
			||||||
                let floatParam;
 | 
					                let floatParam;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // from https://stackoverflow.com/questions/12643009/regular-expression-for-floating-point-numbers
 | 
					                // from https://stackoverflow.com/questions/12643009/regular-expression-for-floating-point-numbers
 | 
				
			||||||
@ -156,10 +130,10 @@ module.exports = function(filters, selectedColumns = 'notes.*') {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                if (floatParam === undefined || isNaN(floatParam)) {
 | 
					                if (floatParam === undefined || isNaN(floatParam)) {
 | 
				
			||||||
                    // if the value can't be parsed as float then we assume that string comparison should be used instead of numeric
 | 
					                    // if the value can't be parsed as float then we assume that string comparison should be used instead of numeric
 | 
				
			||||||
                    whereStmt += `${accessor} ${filter.operator} ?`;
 | 
					                where += `${accessor} ${filter.operator} ?`;
 | 
				
			||||||
                    params.push(filter.value);
 | 
					                    params.push(filter.value);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    whereStmt += `CAST(${accessor} AS DECIMAL) ${filter.operator} ?`;
 | 
					                where += `CAST(${accessor} AS DECIMAL) ${filter.operator} ?`;
 | 
				
			||||||
                    params.push(floatParam);
 | 
					                    params.push(floatParam);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
@ -167,11 +141,6 @@ module.exports = function(filters, selectedColumns = 'notes.*') {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return whereStmt;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const where = parseWhereFilters(filters);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (orderBy.length === 0) {
 | 
					    if (orderBy.length === 0) {
 | 
				
			||||||
        // if no ordering is given then order at least by note title
 | 
					        // if no ordering is given then order at least by note title
 | 
				
			||||||
        orderBy.push("notes.title");
 | 
					        orderBy.push("notes.title");
 | 
				
			||||||
 | 
				
			|||||||
@ -60,20 +60,6 @@ module.exports = function (searchText) {
 | 
				
			|||||||
                operator: '*=*',
 | 
					                operator: '*=*',
 | 
				
			||||||
                value: searchText
 | 
					                value: searchText
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					 | 
				
			||||||
            filters.push({
 | 
					 | 
				
			||||||
                relation: 'or',
 | 
					 | 
				
			||||||
                name: 'attributeName',
 | 
					 | 
				
			||||||
                operator: '*=*',
 | 
					 | 
				
			||||||
                value: searchText
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            filters.push({
 | 
					 | 
				
			||||||
                relation: 'or',
 | 
					 | 
				
			||||||
                name: 'attributeValue',
 | 
					 | 
				
			||||||
                operator: '*=*',
 | 
					 | 
				
			||||||
                value: searchText
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            const tokens = searchText.split(/\s+/);
 | 
					            const tokens = searchText.split(/\s+/);
 | 
				
			||||||
@ -81,27 +67,9 @@ module.exports = function (searchText) {
 | 
				
			|||||||
            for (const token of tokens) {
 | 
					            for (const token of tokens) {
 | 
				
			||||||
                filters.push({
 | 
					                filters.push({
 | 
				
			||||||
                    relation: 'and',
 | 
					                    relation: 'and',
 | 
				
			||||||
                    name: 'sub',
 | 
					 | 
				
			||||||
                    children: [
 | 
					 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            relation: 'or',
 | 
					 | 
				
			||||||
                            name: 'text',
 | 
					                            name: 'text',
 | 
				
			||||||
                            operator: '*=*',
 | 
					                            operator: '*=*',
 | 
				
			||||||
                            value: token
 | 
					                            value: token
 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            relation: 'or',
 | 
					 | 
				
			||||||
                            name: 'attributeName',
 | 
					 | 
				
			||||||
                            operator: '*=*',
 | 
					 | 
				
			||||||
                            value: token
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            relation: 'or',
 | 
					 | 
				
			||||||
                            name: 'attributeValue',
 | 
					 | 
				
			||||||
                            operator: '*=*',
 | 
					 | 
				
			||||||
                            value: token
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    ]
 | 
					 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user