aboutsummaryrefslogtreecommitdiff
path: root/src/server/updateSearch.ts
blob: 906b795f15f372f52cd0fe66550f33be2ca4bcc8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import { Database } from "./database";
import { Cursor } from "mongodb";
import { Search } from "./Search";
import pLimit from 'p-limit';

const suffixMap: { [type: string]: (string | [string, string | ((json: any) => any)]) } = {
    "number": "_n",
    "string": "_t",
    "boolean": "_b",
    // "image": ["_t", "url"],
    "video": ["_t", "url"],
    "pdf": ["_t", "url"],
    "audio": ["_t", "url"],
    "web": ["_t", "url"],
    "date": ["_d", value => new Date(value.date).toISOString()],
    "proxy": ["_i", "fieldId"],
    "list": ["_l", list => {
        const results = [];
        for (const value of list.fields) {
            const term = ToSearchTerm(value);
            if (term) {
                results.push(term.value);
            }
        }
        return results.length ? results : null;
    }]
};

function ToSearchTerm(val: any): { suffix: string, value: any } | undefined {
    if (val === null || val === undefined) {
        return;
    }
    const type = val.__type || typeof val;
    let suffix = suffixMap[type];
    if (!suffix) {
        return;
    }

    if (Array.isArray(suffix)) {
        const accessor = suffix[1];
        if (typeof accessor === "function") {
            val = accessor(val);
        } else {
            val = val[accessor];
        }
        suffix = suffix[0];
    }

    return { suffix, value: val };
}

function getSuffix(value: string | [string, any]): string {
    return typeof value === "string" ? value : value[0];
}

const limit = pLimit(5);
async function update() {
    // await new Promise(res => setTimeout(res, 5));
    console.log("update");
    await Search.Instance.clear();
    const cursor = await Database.Instance.query({});
    console.log("Cleared");
    const updates: any[] = [];
    let numDocs = 0;
    function updateDoc(doc: any) {
        numDocs++;
        if ((numDocs % 50) === 0) {
            console.log("updateDoc " + numDocs);
        }
        // console.log("doc " + numDocs);
        if (doc.__type !== "Doc") {
            return;
        }
        const fields = doc.fields;
        if (!fields) {
            return;
        }
        const update: any = { id: doc._id };
        let dynfield = false;
        for (const key in fields) {
            const value = fields[key];
            const term = ToSearchTerm(value);
            if (term !== undefined) {
                let { suffix, value } = term;
                update[key + suffix] = value;
                dynfield = true;
            }
        }
        if (dynfield) {
            updates.push(update);
            // console.log(updates.length);
        }
    }
    await cursor.forEach(updateDoc);
    console.log(`Updating ${updates.length} documents`);
    const result = await Search.Instance.updateDocuments(updates);
    try {
        console.log(JSON.parse(result).responseHeader.status);
    } catch {
        console.log("Error:");
        // console.log(updates[i]);
        console.log(result);
        console.log("\n");
    }
    // for (let i = 0; i < updates.length; i++) {
    //     console.log(i);
    //     const result = await Search.Instance.updateDocument(updates[i]);
    // try {
    //     console.log(JSON.parse(result).responseHeader.status);
    // } catch {
    //     console.log("Error:");
    //     console.log(updates[i]);
    //     console.log(result);
    //     console.log("\n");
    // }
    // }
    // await Promise.all(updates.map(update => {
    //     return limit(() => Search.Instance.updateDocument(update));
    // }));
    cursor.close();
}

update();