Initial search query parser

This commit is contained in:
Andris Reinman 2023-04-27 15:24:28 +03:00
parent 3f656e878a
commit 83b7353f3f
No known key found for this signature in database
GPG key ID: DC6C83F4D584D364
3 changed files with 26 additions and 5 deletions

View file

@ -508,6 +508,8 @@ module.exports = (db, server, messageHandler, userHandler, storageHandler, setti
const searchSchema = Joi.object().keys({
user: Joi.string().hex().lowercase().length(24).required(),
q: Joi.string().trim().empty('').max(1024).optional(),
mailbox: Joi.string().hex().length(24).empty(''),
thread: Joi.string().hex().length(24).empty(''),
@ -540,7 +542,6 @@ module.exports = (db, server, messageHandler, userHandler, storageHandler, setti
res.charSet('utf-8');
const schema = searchSchema.keys({
q: Joi.string().trim().empty('').max(1024).optional(),
threadCounters: booleanSchema.default(false),
limit: Joi.number().default(20).min(1).max(250),
order: Joi.any().empty('').allow('asc', 'desc').optional(),
@ -591,8 +592,6 @@ module.exports = (db, server, messageHandler, userHandler, storageHandler, setti
query = prepared.query;
}
console.log('SEARCH FILTER', JSON.stringify(filter));
let total = await getFilteredMessageCount(filter);
log.verbose('API', 'Searching %s', JSON.stringify(filter));

View file

@ -142,6 +142,8 @@ function parseSearchQuery(queryStr) {
const getMongoDBQuery = async (db, user, queryStr) => {
const parsed = parseSearchQuery(queryStr);
let hasTextFilter = false;
let walkTree = async node => {
if (Array.isArray(node)) {
let branches = [];
@ -185,6 +187,8 @@ const getMongoDBQuery = async (db, user, queryStr) => {
branch = { $not: branch };
}
hasTextFilter = true;
return branch;
} else if (node.keywords) {
let branches = [];
@ -298,7 +302,14 @@ const getMongoDBQuery = async (db, user, queryStr) => {
};
if (parsed && parsed.length) {
return Object.assign({ user: null }, await walkTree(Array.isArray(parsed) ? { $and: parsed } : parsed), { user });
let filter = await walkTree(Array.isArray(parsed) ? { $and: parsed } : parsed);
let extras = { user };
if (hasTextFilter) {
extras.searchable = true;
}
return Object.assign({ user: null }, filter, extras);
}
return { user: false };

View file

@ -4,6 +4,7 @@ const log = require('npmlog');
const db = require('../db');
const util = require('util');
const prepareSearchFilter = require('../prepare-search-filter');
const { getMongoDBQuery } = require('../search-query');
const ObjectId = require('mongodb').ObjectId;
let run = async (task, data, options) => {
@ -22,7 +23,17 @@ let run = async (task, data, options) => {
action.moveTo = new ObjectId(action.moveTo);
}
const { query, filter } = await prepareSearchFilter(db, user, data);
let query;
let filter;
if (data.q) {
filter = await getMongoDBQuery(db, user, data.q);
query = data.q;
} else {
let prepared = await prepareSearchFilter(db, user, data);
filter = prepared.filter;
query = prepared.query;
}
try {
// getMailboxAsync throws if mailbox is missing or wrong owner