nodebb-plugin-dbsearch 6.2.5 → 6.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/mongo.js +3 -9
- package/lib/postgres.js +11 -11
- package/package.json +1 -1
- package/plugin.json +2 -1
- package/upgrades/dbsearch_change_integer_index.js +60 -0
package/lib/mongo.js
CHANGED
|
@@ -36,8 +36,6 @@ exports.searchIndex = async function (key, data, ids) {
|
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
ids = ids.map(id => parseInt(id, 10));
|
|
40
|
-
|
|
41
39
|
const bulk = db.client.collection(`search${key}`).initializeUnorderedBulkOp();
|
|
42
40
|
ids.forEach((id, index) => {
|
|
43
41
|
const setData = {};
|
|
@@ -47,7 +45,7 @@ exports.searchIndex = async function (key, data, ids) {
|
|
|
47
45
|
}
|
|
48
46
|
});
|
|
49
47
|
|
|
50
|
-
bulk.find({ _id: id }).upsert().updateOne({ $set: setData });
|
|
48
|
+
bulk.find({ _id: String(id) }).upsert().updateOne({ $set: setData });
|
|
51
49
|
});
|
|
52
50
|
|
|
53
51
|
await bulk.execute();
|
|
@@ -100,9 +98,7 @@ exports.searchRemove = async function (key, ids) {
|
|
|
100
98
|
return;
|
|
101
99
|
}
|
|
102
100
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
await db.client.collection(`search${key}`).deleteMany({ _id: { $in: ids } });
|
|
101
|
+
await db.client.collection(`search${key}`).deleteMany({ _id: { $in: ids.map(String) } });
|
|
106
102
|
};
|
|
107
103
|
|
|
108
104
|
exports.chat = {};
|
|
@@ -111,13 +107,11 @@ exports.chat.index = async (data, ids) => {
|
|
|
111
107
|
return;
|
|
112
108
|
}
|
|
113
109
|
|
|
114
|
-
ids = ids.map(id => parseInt(id, 10));
|
|
115
|
-
|
|
116
110
|
const bulk = db.client.collection(`searchchat`).initializeUnorderedBulkOp();
|
|
117
111
|
ids.forEach((id, index) => {
|
|
118
112
|
const d = data[index];
|
|
119
113
|
if (d && d.content && d.uid && d.roomId) {
|
|
120
|
-
bulk.find({ _id: id }).upsert().updateOne({
|
|
114
|
+
bulk.find({ _id: String(id) }).upsert().updateOne({
|
|
121
115
|
$set: {
|
|
122
116
|
content: String(d.content),
|
|
123
117
|
roomId: String(d.roomId),
|
package/lib/postgres.js
CHANGED
|
@@ -13,17 +13,17 @@ pubsub.on('dbsearch-language-changed', (e) => {
|
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
async function initDB() {
|
|
16
|
-
await db.pool.query('CREATE TABLE IF NOT EXISTS "searchtopic" ( "id"
|
|
16
|
+
await db.pool.query('CREATE TABLE IF NOT EXISTS "searchtopic" ( "id" TEXT NOT NULL PRIMARY KEY, "content" TEXT, "uid" TEXT, "cid" BIGINT )');
|
|
17
17
|
await db.pool.query(`CREATE INDEX IF NOT EXISTS "idx__searchtopic__content" ON "searchtopic" USING GIN (to_tsvector('${searchLanguage}', "content"))`);
|
|
18
18
|
await db.pool.query('CREATE INDEX IF NOT EXISTS "idx__searchtopic__uid" ON "searchtopic"("uid")');
|
|
19
19
|
await db.pool.query('CREATE INDEX IF NOT EXISTS "idx__searchtopic__cid" ON "searchtopic"("cid")');
|
|
20
20
|
|
|
21
|
-
await db.pool.query('CREATE TABLE IF NOT EXISTS "searchpost" ( "id"
|
|
21
|
+
await db.pool.query('CREATE TABLE IF NOT EXISTS "searchpost" ( "id" TEXT NOT NULL PRIMARY KEY, "content" TEXT, "uid" TEXT, "cid" BIGINT )');
|
|
22
22
|
await db.pool.query(`CREATE INDEX IF NOT EXISTS "idx__searchpost__content" ON "searchpost" USING GIN (to_tsvector('${searchLanguage}', "content"))`);
|
|
23
23
|
await db.pool.query('CREATE INDEX IF NOT EXISTS "idx__searchpost__uid" ON "searchpost"("uid")');
|
|
24
24
|
await db.pool.query('CREATE INDEX IF NOT EXISTS "idx__searchpost__cid" ON "searchpost"("cid")');
|
|
25
25
|
|
|
26
|
-
await db.pool.query('CREATE TABLE IF NOT EXISTS "searchchat" ( "id"
|
|
26
|
+
await db.pool.query('CREATE TABLE IF NOT EXISTS "searchchat" ( "id" TEXT NOT NULL PRIMARY KEY, "content" TEXT, "rid" BIGINT, "uid" TEXT )');
|
|
27
27
|
await db.pool.query(`CREATE INDEX IF NOT EXISTS "idx__searchchat__content" ON "searchchat" USING GIN (to_tsvector('${searchLanguage}', "content"))`);
|
|
28
28
|
await db.pool.query('CREATE INDEX IF NOT EXISTS "idx__searchchat__rid" ON "searchchat"("rid")');
|
|
29
29
|
await db.pool.query('CREATE INDEX IF NOT EXISTS "idx__searchchat__uid" ON "searchchat"("uid")');
|
|
@@ -64,11 +64,11 @@ exports.searchIndex = async function (key, data, ids) {
|
|
|
64
64
|
return;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
ids = ids.map(
|
|
67
|
+
ids = ids.map(String);
|
|
68
68
|
try {
|
|
69
69
|
await db.pool.query({
|
|
70
70
|
name: `dbsearch-searchIndex-${key}`,
|
|
71
|
-
text: `INSERT INTO "search${key}" SELECT d."id", d."data"->>'content' "content", (d."data"->>'uid')::
|
|
71
|
+
text: `INSERT INTO "search${key}" SELECT d."id", d."data"->>'content' "content", (d."data"->>'uid')::text "uid", (d."data"->>'cid')::bigint "cid" FROM UNNEST($1::text[], $2::jsonb[]) d("id", "data") ON CONFLICT ("id") DO UPDATE SET "content" = COALESCE(EXCLUDED."content", "search${key}"."content"), "uid" = COALESCE(EXCLUDED."uid", "search${key}"."uid"), "cid" = COALESCE(EXCLUDED."cid", "search${key}"."cid")`,
|
|
72
72
|
values: [ids, data],
|
|
73
73
|
});
|
|
74
74
|
} catch (err) {
|
|
@@ -93,7 +93,7 @@ exports.search = async function (key, data, limit) {
|
|
|
93
93
|
try {
|
|
94
94
|
const res = await db.pool.query({
|
|
95
95
|
name: `dbsearch-search-${key}`,
|
|
96
|
-
text: `SELECT ARRAY(SELECT s."id" FROM "search${key}" s WHERE ($1::text IS NULL OR to_tsvector($5::regconfig, "content") @@ plainto_tsquery($5::regconfig, $1::text)) AND ($2::
|
|
96
|
+
text: `SELECT ARRAY(SELECT s."id" FROM "search${key}" s WHERE ($1::text IS NULL OR to_tsvector($5::regconfig, "content") @@ plainto_tsquery($5::regconfig, $1::text)) AND ($2::text[] IS NULL OR "uid" = ANY($2::text[])) AND ($3::bigint[] IS NULL OR "cid" = ANY($3::bigint[])) ORDER BY ts_rank_cd(to_tsvector($5::regconfig, "content"), plainto_tsquery($5::regconfig, $1::text)) DESC, s."id" ASC LIMIT $4::integer) r`,
|
|
97
97
|
values: [data.content, data.uid, data.cid, parseInt(limit, 10), searchLanguage],
|
|
98
98
|
});
|
|
99
99
|
return res.rows[0].r;
|
|
@@ -108,11 +108,11 @@ exports.searchRemove = async function (key, ids) {
|
|
|
108
108
|
return;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
ids = ids.map(
|
|
111
|
+
ids = ids.map(String);
|
|
112
112
|
try {
|
|
113
113
|
await db.pool.query({
|
|
114
114
|
name: `dbsearch-searchRemove-${key}`,
|
|
115
|
-
text: `DELETE FROM "search${key}" s WHERE s."id" = ANY($1::
|
|
115
|
+
text: `DELETE FROM "search${key}" s WHERE s."id" = ANY($1::text[])`,
|
|
116
116
|
values: [ids],
|
|
117
117
|
});
|
|
118
118
|
} catch (err) {
|
|
@@ -126,11 +126,11 @@ exports.chat.index = async (data, ids) => {
|
|
|
126
126
|
return;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
ids = ids.map(
|
|
129
|
+
ids = ids.map(String);
|
|
130
130
|
try {
|
|
131
131
|
await db.pool.query({
|
|
132
132
|
name: `dbsearch-searchIndex-chat`,
|
|
133
|
-
text: `INSERT INTO "searchchat" SELECT d."id", d."data"->>'content' "content", (d."data"->>'uid')::
|
|
133
|
+
text: `INSERT INTO "searchchat" SELECT d."id", d."data"->>'content' "content", (d."data"->>'uid')::text "uid", (d."data"->>'roomId')::bigint "rid" FROM UNNEST($1::text[], $2::jsonb[]) d("id", "data") ON CONFLICT ("id") DO UPDATE SET "content" = COALESCE(EXCLUDED."content", "searchchat"."content"), "uid" = COALESCE(EXCLUDED."uid", "searchchat"."uid"), "rid" = COALESCE(EXCLUDED."rid", "searchchat"."rid")`,
|
|
134
134
|
values: [ids, data],
|
|
135
135
|
});
|
|
136
136
|
} catch (err) {
|
|
@@ -155,7 +155,7 @@ exports.chat.search = async (data, limit) => {
|
|
|
155
155
|
try {
|
|
156
156
|
const res = await db.pool.query({
|
|
157
157
|
name: `dbsearch-search-chat`,
|
|
158
|
-
text: `SELECT ARRAY(SELECT s."id" FROM "searchchat" s WHERE ($1::text IS NULL OR to_tsvector($5::regconfig, "content") @@ plainto_tsquery($5::regconfig, $1::text)) AND ($2::
|
|
158
|
+
text: `SELECT ARRAY(SELECT s."id" FROM "searchchat" s WHERE ($1::text IS NULL OR to_tsvector($5::regconfig, "content") @@ plainto_tsquery($5::regconfig, $1::text)) AND ($2::text[] IS NULL OR "uid" = ANY($2::text[])) AND ($3::bigint[] IS NULL OR "rid" = ANY($3::bigint[])) ORDER BY ts_rank_cd(to_tsvector($5::regconfig, "content"), plainto_tsquery($5::regconfig, $1::text)) DESC, s."id" ASC LIMIT $4::integer) r`,
|
|
159
159
|
values: [data.content, data.uid, data.roomId, parseInt(limit, 10), searchLanguage],
|
|
160
160
|
});
|
|
161
161
|
return res.rows[0].r;
|
package/package.json
CHANGED
package/plugin.json
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
"url": "https://github.com/barisusakli/nodebb-plugin-dbsearch",
|
|
6
6
|
"library": "./index.js",
|
|
7
7
|
"upgrades": [
|
|
8
|
-
"upgrades/dbsearch_change_mongodb_schema.js"
|
|
8
|
+
"upgrades/dbsearch_change_mongodb_schema.js",
|
|
9
|
+
"upgrades/dbsearch_change_integer_index.js"
|
|
9
10
|
],
|
|
10
11
|
"hooks": [
|
|
11
12
|
{ "hook": "static:app.load", "method": "init" },
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
const db = module.parent.require('./database');
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
name: 'Changing integer search indices to string',
|
|
8
|
+
timestamp: Date.UTC(2025, 0, 27),
|
|
9
|
+
method: async function () {
|
|
10
|
+
const { progress } = this;
|
|
11
|
+
const nconf = require.main.require('nconf');
|
|
12
|
+
const mainDB = nconf.get('database');
|
|
13
|
+
if (mainDB === 'redis') {
|
|
14
|
+
// redis is not affected, since everything is string already
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function convertIdToString(collection, docs) {
|
|
19
|
+
for (const doc of docs) {
|
|
20
|
+
if (doc._id) {
|
|
21
|
+
const stringId = doc._id.toString();
|
|
22
|
+
// eslint-disable-next-line no-await-in-loop
|
|
23
|
+
await db.client.collection(collection).insertOne({
|
|
24
|
+
...doc,
|
|
25
|
+
_id: stringId,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// eslint-disable-next-line no-await-in-loop
|
|
29
|
+
await db.client.collection(collection).deleteOne({ _id: doc._id });
|
|
30
|
+
}
|
|
31
|
+
progress.incr(1);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (mainDB === 'mongo') {
|
|
36
|
+
const topics = await db.client.collection('searchtopic').find({}).toArray();
|
|
37
|
+
const posts = await db.client.collection('searchposts').find({}).toArray();
|
|
38
|
+
const chats = await db.client.collection('searchchat').find({}).toArray();
|
|
39
|
+
|
|
40
|
+
progress.total = topics.length + posts.length + chats.length;
|
|
41
|
+
|
|
42
|
+
await convertIdToString('searchtopic', topics);
|
|
43
|
+
await convertIdToString('searchposts', posts);
|
|
44
|
+
await convertIdToString('searchchat', chats);
|
|
45
|
+
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (mainDB === 'postgres') {
|
|
50
|
+
await db.client.query('ALTER TABLE searchtopic ALTER COLUMN id TYPE text USING id::bigint');
|
|
51
|
+
await db.client.query('ALTER TABLE searchtopic ALTER COLUMN uid TYPE text USING uid::bigint');
|
|
52
|
+
|
|
53
|
+
await db.client.query('ALTER TABLE searchpost ALTER COLUMN id TYPE text USING id::bigint');
|
|
54
|
+
await db.client.query('ALTER TABLE searchpost ALTER COLUMN uid TYPE text USING uid::bigint');
|
|
55
|
+
|
|
56
|
+
await db.client.query('ALTER TABLE searchchat ALTER COLUMN id TYPE text USING id::bigint');
|
|
57
|
+
await db.client.query('ALTER TABLE searchchat ALTER COLUMN uid TYPE text USING uid::bigint');
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
};
|