1
0
mirror of https://github.com/nextapps-de/flexsearch.git synced 2025-09-27 13:58:59 +02:00
Files
flexsearch/dist/module-debug/resolve/xor.js
2025-03-17 01:13:36 +01:00

172 lines
4.6 KiB
JavaScript

import Resolver from "../resolver.js";
import default_resolver from "./default.js";
import { create_object } from "../common.js";
import { ResolverOptions } from "../type.js";
Resolver.prototype.xor = function () {
const self = this;
let args = arguments,
first_argument = args[0];
if (first_argument.then) {
return first_argument.then(function () {
return self.xor.apply(self, args);
});
}
if (first_argument[0]) {
// fix false passed parameter style
if (first_argument[0].index) {
return this.xor.apply(this, first_argument);
}
}
let final = [],
promises = [],
limit = 0,
offset = 0,
enrich,
resolve;
for (let i = 0, query; i < args.length; i++) {
query = /** @type {string|ResolverOptions} */args[i];
if (query) {
limit = query.limit || 0;
offset = query.offset || 0;
enrich = query.enrich;
resolve = query.resolve;
let result;
if (query.constructor === Resolver) {
result = query.result;
} else if (query.constructor === Array) {
result = query;
} else if (query.index) {
query.resolve = /* suggest */ /* append: */ /* enrich */!1;
result = query.index.search(query).result;
} else if (query.or) {
result = this.or(query.or);
} else if (query.and) {
result = this.and(query.and);
} else if (query.not) {
result = this.not(query.not);
} else {
continue;
}
final[i] = result;
if (result.then) {
promises.push(result); //{ query, result };
}
}
}
if (promises.length) {
return Promise.all(promises).then(function () {
self.result.length && (final = [self.result].concat(final));
self.result = exclusive(final, limit, offset, enrich, !resolve, self.boostval);
return resolve ? self.result : self;
});
}
if (final.length) {
this.result.length && (final = [this.result].concat(final));
this.result = exclusive(final, limit, offset, enrich, !resolve, self.boostval);
}
return resolve ? this.result : this;
};
/**
* @param result
* @param limit
* @param offset
* @param enrich
* @param resolve
* @param boost
* @return {Array}
*/
function exclusive(result, limit, offset, enrich, resolve, boost) {
if (!result.length) {
// todo remove
//console.log("Empty Result")
return result;
}
if (2 > result.length) {
// todo remove
//console.log("Single Result")
if (resolve) {
return default_resolver(result[0], limit, offset, enrich);
} else {
return result[0];
}
}
const final = [],
check = create_object();
let maxres = 0;
for (let i = 0, res; i < result.length; i++) {
res = result[i];
if (!res) continue;
for (let j = 0, ids; j < res.length; j++) {
ids = res[j];
if (!ids) continue;
if (maxres < ids.length) maxres = ids.length;
for (let k = 0, id; k < ids.length; k++) {
id = ids[k];
check[id] ? check[id]++ : check[id] = 1;
}
}
}
for (let j = 0, ids, count = 0; j < maxres; j++) {
for (let i = 0, res; i < result.length; i++) {
res = result[i];
if (!res) continue;
ids = res[j];
if (!ids) continue;
for (let k = 0, id; k < ids.length; k++) {
id = ids[k];
if (1 === check[id]) {
if (offset) {
offset--;
continue;
}
if (resolve) {
final.push(id);
if (final.length === limit) {
return final;
}
} else {
// shift resolution by boost (inverse)
const index = j + (i ? boost : 0);
final[index] || (final[index] = []);
final[index].push(id);
if (++count === limit) {
return final;
}
}
}
}
}
}
//this.boost = 0;
return final;
}