mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
add possibility to debug search queries by logging expression tree, #1655
This commit is contained in:
parent
0c9a11db6f
commit
859465841d
35
src/public/app/widgets/search_options/debug.js
Normal file
35
src/public/app/widgets/search_options/debug.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import AbstractSearchOption from "./abstract_search_option.js";
|
||||||
|
|
||||||
|
const TPL = `
|
||||||
|
<tr data-search-option-conf="debug">
|
||||||
|
<td colSpan="2">
|
||||||
|
<span class="bx bx-bug"></span>
|
||||||
|
|
||||||
|
Debug
|
||||||
|
</td>
|
||||||
|
<td class="button-column">
|
||||||
|
<div class="dropdown help-dropdown">
|
||||||
|
<span class="bx bx-help-circle icon-action" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></span>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right p-4">
|
||||||
|
<p>Debug will print extra debugging information into the console to aid in debugging complex queries.</p>
|
||||||
|
|
||||||
|
<p>To access the debug information, execute query and click on "Show backend log" in top left corner.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span class="bx bx-x icon-action search-option-del"></span>
|
||||||
|
</td>
|
||||||
|
</tr>`;
|
||||||
|
|
||||||
|
export default class Debug extends AbstractSearchOption {
|
||||||
|
static get optionName() { return "debug" };
|
||||||
|
static get attributeType() { return "label" };
|
||||||
|
|
||||||
|
static async create(noteId) {
|
||||||
|
await AbstractSearchOption.setAttribute(noteId,'label', 'debug');
|
||||||
|
}
|
||||||
|
|
||||||
|
doRender() {
|
||||||
|
return $(TPL);
|
||||||
|
}
|
||||||
|
}
|
@ -20,6 +20,7 @@ import OrderBy from "../search_options/order_by.js";
|
|||||||
import SearchScript from "../search_options/search_script.js";
|
import SearchScript from "../search_options/search_script.js";
|
||||||
import Limit from "../search_options/limit.js";
|
import Limit from "../search_options/limit.js";
|
||||||
import DeleteNoteRevisionsSearchAction from "../search_actions/delete_note_revisions.js";
|
import DeleteNoteRevisionsSearchAction from "../search_actions/delete_note_revisions.js";
|
||||||
|
import Debug from "../search_options/debug.js";
|
||||||
|
|
||||||
const TPL = `
|
const TPL = `
|
||||||
<div class="search-definition-widget">
|
<div class="search-definition-widget">
|
||||||
@ -113,6 +114,11 @@ const TPL = `
|
|||||||
limit
|
limit
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-sm" data-search-option-add="debug" title="Debug will print extra debugging information into the console to aid in debugging complex queries">
|
||||||
|
<span class="bx bx-bug"></span>
|
||||||
|
debug
|
||||||
|
</button>
|
||||||
|
|
||||||
<div class="dropdown" style="display: inline-block;">
|
<div class="dropdown" style="display: inline-block;">
|
||||||
<button class="btn btn-sm dropdown-toggle action-add-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
<button class="btn btn-sm dropdown-toggle action-add-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
<span class="bx bxs-zap"></span>
|
<span class="bx bxs-zap"></span>
|
||||||
@ -173,7 +179,8 @@ const OPTION_CLASSES = [
|
|||||||
FastSearch,
|
FastSearch,
|
||||||
IncludeArchivedNotes,
|
IncludeArchivedNotes,
|
||||||
OrderBy,
|
OrderBy,
|
||||||
Limit
|
Limit,
|
||||||
|
Debug
|
||||||
];
|
];
|
||||||
|
|
||||||
const ACTION_CLASSES = {};
|
const ACTION_CLASSES = {};
|
||||||
|
@ -24,6 +24,7 @@ async function search(note) {
|
|||||||
orderBy: note.getLabelValue('orderBy'),
|
orderBy: note.getLabelValue('orderBy'),
|
||||||
orderDirection: note.getLabelValue('orderDirection'),
|
orderDirection: note.getLabelValue('orderDirection'),
|
||||||
limit: note.getLabelValue('limit'),
|
limit: note.getLabelValue('limit'),
|
||||||
|
debug: note.hasLabel('debug'),
|
||||||
fuzzyAttributeSearch: false
|
fuzzyAttributeSearch: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ class AncestorExp extends Expression {
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
this.ancestorNoteId = ancestorNoteId;
|
this.ancestorNoteId = ancestorNoteId;
|
||||||
|
this.ancestorDepth = ancestorDepth; // for DEBUG mode
|
||||||
this.ancestorDepthComparator = this.getComparator(ancestorDepth);
|
this.ancestorDepthComparator = this.getComparator(ancestorDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
class Expression {
|
class Expression {
|
||||||
|
constructor() {
|
||||||
|
this.name = this.constructor.name; // for DEBUG mode to have expression name as part of dumped JSON
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {NoteSet} inputNoteSet
|
* @param {NoteSet} inputNoteSet
|
||||||
* @param {object} executionContext
|
* @param {object} executionContext
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
const Expression = require('./expression');
|
const Expression = require('./expression');
|
||||||
const NoteSet = require('../note_set');
|
const NoteSet = require('../note_set');
|
||||||
|
const buildComparator = require("../services/build_comparator.js");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search string is lower cased for case insensitive comparison. But when retrieving properties
|
* Search string is lower cased for case insensitive comparison. But when retrieving properties
|
||||||
@ -33,11 +34,13 @@ class PropertyComparisonExp extends Expression {
|
|||||||
return name in PROP_MAPPING;
|
return name in PROP_MAPPING;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(searchContext, propertyName, comparator) {
|
constructor(searchContext, propertyName, operator, comparedValue) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.propertyName = PROP_MAPPING[propertyName];
|
this.propertyName = PROP_MAPPING[propertyName];
|
||||||
this.comparator = comparator;
|
this.operator = operator; // for DEBUG mode
|
||||||
|
this.comparedValue = comparedValue; // for DEBUG mode
|
||||||
|
this.comparator = buildComparator(operator, comparedValue);
|
||||||
|
|
||||||
if (['contentsize', 'notesize', 'revisioncount'].includes(this.propertyName)) {
|
if (['contentsize', 'notesize', 'revisioncount'].includes(this.propertyName)) {
|
||||||
searchContext.dbLoadNeeded = true;
|
searchContext.dbLoadNeeded = true;
|
||||||
|
@ -11,6 +11,7 @@ class SearchContext {
|
|||||||
this.orderBy = params.orderBy;
|
this.orderBy = params.orderBy;
|
||||||
this.orderDirection = params.orderDirection;
|
this.orderDirection = params.orderDirection;
|
||||||
this.limit = params.limit;
|
this.limit = params.limit;
|
||||||
|
this.debug = params.debug;
|
||||||
this.fuzzyAttributeSearch = !!params.fuzzyAttributeSearch;
|
this.fuzzyAttributeSearch = !!params.fuzzyAttributeSearch;
|
||||||
this.highlightedTokens = [];
|
this.highlightedTokens = [];
|
||||||
this.originalQuery = "";
|
this.originalQuery = "";
|
||||||
|
@ -194,7 +194,7 @@ function getExpression(tokens, searchContext, level = 0) {
|
|||||||
i += 2;
|
i += 2;
|
||||||
|
|
||||||
return new OrExp([
|
return new OrExp([
|
||||||
new PropertyComparisonExp(searchContext, 'title', buildComparator('*=*', tokens[i].token)),
|
new PropertyComparisonExp(searchContext, 'title', '*=*', tokens[i].token),
|
||||||
new NoteContentProtectedFulltextExp('*=*', [tokens[i].token]),
|
new NoteContentProtectedFulltextExp('*=*', [tokens[i].token]),
|
||||||
new NoteContentUnprotectedFulltextExp('*=*', [tokens[i].token])
|
new NoteContentUnprotectedFulltextExp('*=*', [tokens[i].token])
|
||||||
]);
|
]);
|
||||||
@ -208,14 +208,7 @@ function getExpression(tokens, searchContext, level = 0) {
|
|||||||
|
|
||||||
const comparedValue = resolveConstantOperand();
|
const comparedValue = resolveConstantOperand();
|
||||||
|
|
||||||
const comparator = buildComparator(operator, comparedValue);
|
return new PropertyComparisonExp(searchContext, propertyName, operator, comparedValue);
|
||||||
|
|
||||||
if (!comparator) {
|
|
||||||
searchContext.addError(`Can't find operator '${operator}' in ${context(i - 2)}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new PropertyComparisonExp(searchContext, propertyName, comparator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
searchContext.addError(`Unrecognized note property "${tokens[i].token}" in ${context(i)}`);
|
searchContext.addError(`Unrecognized note property "${tokens[i].token}" in ${context(i)}`);
|
||||||
@ -411,8 +404,8 @@ function getExpression(tokens, searchContext, level = 0) {
|
|||||||
|
|
||||||
function parse({fulltextTokens, expressionTokens, searchContext}) {
|
function parse({fulltextTokens, expressionTokens, searchContext}) {
|
||||||
let exp = AndExp.of([
|
let exp = AndExp.of([
|
||||||
searchContext.includeArchivedNotes ? null : new PropertyComparisonExp(searchContext, "isarchived", buildComparator("=", "false")),
|
searchContext.includeArchivedNotes ? null : new PropertyComparisonExp(searchContext, "isarchived", "=", "false"),
|
||||||
searchContext.ancestorNoteId ? new AncestorExp(searchContext.ancestorNoteId, searchContext.ancestorDepth) : null,
|
(searchContext.ancestorNoteId && searchContext.ancestorNoteId !== 'root') ? new AncestorExp(searchContext.ancestorNoteId, searchContext.ancestorDepth) : null,
|
||||||
getFulltext(fulltextTokens, searchContext),
|
getFulltext(fulltextTokens, searchContext),
|
||||||
getExpression(expressionTokens, searchContext)
|
getExpression(expressionTokens, searchContext)
|
||||||
]);
|
]);
|
||||||
|
@ -127,6 +127,12 @@ function parseQueryToExpression(query, searchContext) {
|
|||||||
originalQuery: query
|
originalQuery: query
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (searchContext.debug) {
|
||||||
|
log.info(`Fulltext tokens: ` + JSON.stringify(fulltextTokens));
|
||||||
|
log.info(`Expression tokens: ` + JSON.stringify(structuredExpressionTokens, null, 4));
|
||||||
|
log.info("Expression tree: " + JSON.stringify(expression, null, 4));
|
||||||
|
}
|
||||||
|
|
||||||
return expression;
|
return expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user