1
0
mirror of https://github.com/nextapps-de/flexsearch.git synced 2025-10-01 07:36:40 +02:00
Files
flexsearch/dist/module-debug/document/add.js
Thomas Wilkerling 25e4b5d712 bundle pre-release
2025-03-17 01:12:32 +01:00

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);
}
}
}