mirror of
https://github.com/nextapps-de/flexsearch.git
synced 2025-10-01 07:36:40 +02:00
244 lines
7.4 KiB
JavaScript
244 lines
7.4 KiB
JavaScript
|
|
import { create_object, is_array, is_object, is_string, parse_simple } from "../common.js";
|
|
import { KeystoreArray } from "../keystore.js";
|
|
import Document from "../document.js";
|
|
|
|
/**
|
|
*
|
|
* @param id
|
|
* @param content
|
|
* @param {boolean=} _append
|
|
* @returns {Document|Promise}
|
|
*/
|
|
|
|
Document.prototype.add = function (id, content, _append) {
|
|
|
|
if (is_object(id)) {
|
|
|
|
content = id;
|
|
id = parse_simple(content, this.key);
|
|
}
|
|
|
|
if (content && (id || 0 === id)) {
|
|
|
|
if (!_append && this.reg.has(id)) {
|
|
return this.update(id, content);
|
|
}
|
|
|
|
// this.field does not include db tag indexes
|
|
for (let i = 0, tree; i < this.field.length; i++) {
|
|
|
|
tree = this.tree[i];
|
|
|
|
const index = this.index.get(this.field[i]);
|
|
if ("function" == typeof tree) {
|
|
const tmp = tree(content);
|
|
if (tmp) {
|
|
index.add(id, tmp, /* suggest */ /* append: */!1, /* tag? */ /* stringify */ /* stringify */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/);
|
|
}
|
|
} else {
|
|
const filter = tree._filter;
|
|
if (filter && !filter(content)) {
|
|
continue;
|
|
}
|
|
if (tree instanceof String) {
|
|
tree = ["" + tree];
|
|
} else if (is_string(tree)) {
|
|
tree = [tree];
|
|
}
|
|
add_index(content, tree, this.marker, 0, index, id, tree[0], _append);
|
|
}
|
|
}
|
|
|
|
if (this.tag) {
|
|
|
|
//console.log(this.tag, this.tagtree)
|
|
|
|
for (let x = 0; x < this.tagtree.length; x++) {
|
|
let tree = this.tagtree[x],
|
|
field = this.tagfield[x],
|
|
ref = this.tag.get(field),
|
|
dupes = create_object(),
|
|
tags;
|
|
|
|
|
|
if ("function" == typeof tree) {
|
|
tags = tree(content);
|
|
if (!tags) continue;
|
|
} else {
|
|
const filter = tree._filter;
|
|
if (filter && !filter(content)) {
|
|
continue;
|
|
}
|
|
if (tree instanceof String) {
|
|
tree = "" + tree;
|
|
}
|
|
tags = parse_simple(content, tree);
|
|
}
|
|
|
|
if (!ref || !tags) {
|
|
ref || console.warn("Tag '" + field + "' was not found");
|
|
continue;
|
|
}
|
|
|
|
if (is_string(tags)) {
|
|
tags = [tags];
|
|
}
|
|
|
|
for (let i = 0, tag, arr; i < tags.length; i++) {
|
|
|
|
tag = tags[i];
|
|
//console.log(this.tag, tag, key, field)
|
|
|
|
if (!dupes[tag]) {
|
|
dupes[tag] = 1;
|
|
|
|
let tmp = ref.get(tag);
|
|
|
|
tmp ? arr = tmp : ref.set(tag, arr = []);
|
|
|
|
if (!_append || ! /** @type {!Array|KeystoreArray} */arr.includes(id)) {
|
|
|
|
// auto-upgrade to keystore array if max size exceeded
|
|
if (2147483647 === arr.length /*|| !(arr instanceof KeystoreArray)*/) {
|
|
const keystore = new KeystoreArray(arr);
|
|
if (this.fastupdate) {
|
|
for (let value of this.reg.values()) {
|
|
if (value.includes(arr)) {
|
|
value[value.indexOf(arr)] = keystore;
|
|
}
|
|
}
|
|
}
|
|
ref.set(tag, arr = keystore);
|
|
}
|
|
|
|
|
|
arr.push(id);
|
|
|
|
// add a reference to the register for fast updates
|
|
if (this.fastupdate) {
|
|
const tmp = this.reg.get(id);
|
|
tmp ? tmp.push(arr) : this.reg.set(id, [arr]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this.store && (!_append || !this.store.has(id))) {
|
|
|
|
let payload;
|
|
|
|
if (this.storetree) {
|
|
|
|
payload = create_object();
|
|
|
|
for (let i = 0, tree; i < this.storetree.length; i++) {
|
|
tree = this.storetree[i];
|
|
|
|
const filter = tree._filter;
|
|
if (filter && !filter(content)) {
|
|
continue;
|
|
}
|
|
let custom;
|
|
if ("function" == typeof tree) {
|
|
custom = tree(content);
|
|
if (!custom) continue;
|
|
tree = [tree._field];
|
|
} else if (is_string(tree) || tree instanceof String) {
|
|
payload[tree] = content[tree];
|
|
continue;
|
|
}
|
|
|
|
store_value(content, payload, tree, 0, tree[0], custom);
|
|
}
|
|
}
|
|
|
|
this.store.set(id, payload || content);
|
|
}
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
// TODO support generic function created from string when tree depth > 1
|
|
|
|
/**
|
|
* @param obj
|
|
* @param store
|
|
* @param tree
|
|
* @param pos
|
|
* @param key
|
|
* @param {*=} custom
|
|
*/
|
|
|
|
function store_value(obj, store, tree, pos, key, custom) {
|
|
|
|
obj = obj[key];
|
|
|
|
// reached target field
|
|
if (pos === tree.length - 1) {
|
|
|
|
// store target value
|
|
store[key] = custom || obj;
|
|
} else if (obj) {
|
|
|
|
if (is_array(obj)) {
|
|
|
|
store = store[key] = Array(obj.length);
|
|
|
|
for (let i = 0; i < obj.length; i++) {
|
|
// do not increase pos (an array is not a field)
|
|
store_value(obj, store, tree, pos, i);
|
|
}
|
|
} else {
|
|
|
|
store = store[key] || (store[key] = create_object());
|
|
key = tree[++pos];
|
|
store_value(obj, store, tree, pos, key);
|
|
}
|
|
}
|
|
}
|
|
|
|
function add_index(obj, tree, marker, pos, index, id, key, _append) {
|
|
|
|
if (obj = obj[key]) {
|
|
|
|
// reached target field
|
|
if (pos === tree.length - 1) {
|
|
|
|
// handle target value
|
|
if (is_array(obj)) {
|
|
|
|
// append array contents so each entry gets a new scoring context
|
|
if (marker[pos]) {
|
|
for (let i = 0; i < obj.length; i++) {
|
|
index.add(id, obj[i], !0, !0);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// or join array contents and use one scoring context
|
|
obj = obj.join(" ");
|
|
}
|
|
|
|
index.add(id, obj, _append, !0);
|
|
} else {
|
|
|
|
if (is_array(obj)) {
|
|
for (let i = 0; i < obj.length; i++) {
|
|
// do not increase index, an array is not a field
|
|
add_index(obj, tree, marker, pos, index, id, i, _append);
|
|
}
|
|
} else {
|
|
key = tree[++pos];
|
|
add_index(obj, tree, marker, pos, index, id, key, _append);
|
|
}
|
|
}
|
|
} else {
|
|
if (index.db) {
|
|
index.remove(id);
|
|
}
|
|
}
|
|
} |