nodebb-plugin-dbsearch 6.3.3 → 6.3.5

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/README.md CHANGED
@@ -1,10 +1,10 @@
1
- # NodeBB Plugin DB Search
2
-
3
- A Plugin that lets users search posts and topics
4
-
5
- ## Installation
6
-
7
- npm install nodebb-plugin-dbsearch
8
-
9
-
10
-
1
+ # NodeBB Plugin DB Search
2
+
3
+ A Plugin that lets users search posts and topics
4
+
5
+ ## Installation
6
+
7
+ npm install nodebb-plugin-dbsearch
8
+
9
+
10
+
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- 'use strict';
2
-
3
- module.exports = require('./lib/dbsearch');
4
-
1
+ 'use strict';
2
+
3
+ module.exports = require('./lib/dbsearch');
4
+
package/lib/dbsearch.js CHANGED
@@ -247,9 +247,9 @@ search.filterMessagingSearchMessages = async function (data) {
247
247
 
248
248
  search.reindex = async function () {
249
249
  await db.setObject('nodebb-plugin-dbsearch', {
250
- topicsIndexed: 0,
251
- postsIndexed: 0,
252
- messagesIndexed: 0,
250
+ topicsProgress: 0,
251
+ postsProgress: 0,
252
+ messagesProgress: 0,
253
253
  working: 1,
254
254
  });
255
255
  await Promise.all([
@@ -264,8 +264,11 @@ search.reindex = async function () {
264
264
 
265
265
  async function reIndexTopics() {
266
266
  await batch.processSortedSet('topics:tid', async (tids) => {
267
- const topicData = await topics.getTopicsFields(tids, ['tid', 'title', 'uid', 'cid', 'deleted', 'timestamp']);
267
+ const topicData = await topics.getTopicsFields(tids, [
268
+ 'tid', 'title', 'uid', 'cid', 'deleted', 'timestamp',
269
+ ]);
268
270
  await topicsSave(topicData);
271
+ await db.incrObjectFieldBy('nodebb-plugin-dbsearch', 'topicsProgress', tids.length);
269
272
  }, {
270
273
  batch: batchSize,
271
274
  });
@@ -306,7 +309,6 @@ async function topicsSave(topics) {
306
309
 
307
310
  const result = await plugins.hooks.fire('filter:search.indexTopics', { data: data, tids: tids, topics: topics });
308
311
  await db.searchIndex('topic', result.data, result.tids);
309
- await db.incrObjectFieldBy('nodebb-plugin-dbsearch', 'topicsIndexed', result.tids.length);
310
312
  }
311
313
 
312
314
  async function reIndexPosts() {
@@ -323,6 +325,7 @@ async function reIndexPosts() {
323
325
  });
324
326
  postData = postData.filter(post => tidToTopic[post.tid].deleted !== 1);
325
327
  await postsSave(postData);
328
+ await db.incrObjectFieldBy('nodebb-plugin-dbsearch', 'postsProgress', pids.length);
326
329
  }, {
327
330
  batch: batchSize,
328
331
  });
@@ -363,7 +366,6 @@ async function postsSave(posts) {
363
366
 
364
367
  const result = await plugins.hooks.fire('filter:search.indexPosts', { data: data, pids: pids, posts: posts });
365
368
  await db.searchIndex('post', result.data, result.pids);
366
- await db.incrObjectFieldBy('nodebb-plugin-dbsearch', 'postsIndexed', result.pids.length);
367
369
  }
368
370
 
369
371
  async function reIndexMessages() {
@@ -371,13 +373,16 @@ async function reIndexMessages() {
371
373
  let messageData = await messaging.getMessagesFields(mids, ['mid', 'content', 'roomId', 'fromuid', 'deleted', 'system']);
372
374
  messageData = messageData.filter(p => p && p.deleted !== 1 && p.system !== 1);
373
375
  await messagesSave(messageData);
376
+ await db.incrObjectFieldBy('nodebb-plugin-dbsearch', 'messagesProgress', mids.length);
374
377
  }, {
375
378
  batch: batchSize,
376
379
  });
377
380
  }
378
381
 
379
382
  async function messagesSave(msgs) {
380
- msgs = msgs.filter(m => m && utils.isNumber(m.mid) && parseInt(m.deleted, 10) !== 1 && parseInt(m.system, 10) !== 1);
383
+ msgs = msgs.filter(
384
+ m => m && utils.isNumber(m.mid) && parseInt(m.deleted, 10) !== 1 && parseInt(m.system, 10) !== 1
385
+ );
381
386
 
382
387
  let data = msgs.map((msgData) => {
383
388
  const indexData = {};
@@ -404,19 +409,11 @@ async function messagesSave(msgs) {
404
409
 
405
410
  const result = await plugins.hooks.fire('filter:search.indexMessages', { data: data, mids: mids, messages: msgs });
406
411
  await searchModule.chat.index(result.data, result.mids);
407
- await db.incrObjectFieldBy('nodebb-plugin-dbsearch', 'messagesIndexed', result.mids.length);
408
412
  }
409
413
 
410
414
  async function searchRemove(key, ids) {
411
415
  ids = ids.filter(id => id && utils.isNumber(id));
412
416
  await db.searchRemove(key, ids);
413
- if (key === 'topic') {
414
- await db.incrObjectFieldBy('nodebb-plugin-dbsearch', 'topicsIndexed', -ids.length);
415
- } else if (key === 'post') {
416
- await db.incrObjectFieldBy('nodebb-plugin-dbsearch', 'postsIndexed', -ids.length);
417
- } else if (key === 'chat') {
418
- await db.incrObjectFieldBy('nodebb-plugin-dbsearch', 'messagesIndexed', -ids.length);
419
- }
420
417
  }
421
418
 
422
419
  async function reIndexTids(tids) {
@@ -468,6 +465,14 @@ async function reIndexPids(pids, topic) {
468
465
 
469
466
  async function renderAdmin(req, res) {
470
467
  const results = await getGlobalAndPluginData();
468
+ const [topicsIndexed, postsIndexed, messagesIndexed] = await Promise.all([
469
+ searchModule.getIndexedTopicCount(),
470
+ searchModule.getIndexedPostCount(),
471
+ searchModule.getIndexedChatMessageCount(),
472
+ ]);
473
+ results.plugin.topicsIndexed = parseInt(topicsIndexed, 10) || 0;
474
+ results.plugin.postsIndexed = parseInt(postsIndexed, 10) || 0;
475
+ results.plugin.messagesIndexed = parseInt(messagesIndexed, 10) || 0;
471
476
  results.plugin.progressData = await getProgress();
472
477
  results.plugin.title = 'DB Search';
473
478
  res.render('admin/plugins/dbsearch', results.plugin);
@@ -498,14 +503,12 @@ socketAdmin.plugins.dbsearch.checkProgress = async function () {
498
503
 
499
504
  async function getPluginData() {
500
505
  const data = await db.getObject('nodebb-plugin-dbsearch') || {};
501
- data.topicsIndexed = parseInt(data.topicsIndexed, 10) || 0;
502
- data.postsIndexed = parseInt(data.postsIndexed, 10) || 0;
503
- data.messagesIndexed = parseInt(data.messagesIndexed, 10) || 0;
506
+
504
507
  data.excludeCategories = data.excludeCategories || '[]';
505
508
  data.postLimit = data.postLimit || defaultPostLimit;
506
509
  data.topicLimit = data.topicLimit || defaultTopicLimit;
507
510
  data.indexLanguage = data.indexLanguage || 'en';
508
- data.working = data.working || 0;
511
+ data.working = parseInt(data.working, 10) || 0;
509
512
 
510
513
  try {
511
514
  data.excludeCategories = JSON.parse(data.excludeCategories);
@@ -537,9 +540,6 @@ async function getGlobalAndPluginData() {
537
540
  plugin.messageCount = parseInt(global.messageCount, 10);
538
541
  plugin.topicLimit = plugin.topicLimit || defaultTopicLimit;
539
542
  plugin.postLimit = plugin.postLimit || defaultPostLimit;
540
- plugin.topicsIndexed = plugin.topicsIndexed > plugin.topicCount ? plugin.topicCount : plugin.topicsIndexed;
541
- plugin.postsIndexed = plugin.postsIndexed > plugin.postCount ? plugin.postCount : plugin.postsIndexed;
542
- plugin.messagesIndexed = plugin.messagesIndexed > plugin.messageCount ? plugin.messageCount : plugin.messagesIndexed;
543
543
  plugin.languageSupported = languageSupported;
544
544
  plugin.languages = languages;
545
545
  plugin.indexLanguage = plugin.indexLanguage || 'en';
@@ -557,21 +557,18 @@ async function getGlobalAndPluginData() {
557
557
  async function getProgress() {
558
558
  const [global, pluginData] = await Promise.all([
559
559
  db.getObjectFields('global', ['topicCount', 'postCount', 'messageCount']),
560
- getPluginData(),
560
+ db.getObjectFields('nodebb-plugin-dbsearch', ['topicsProgress', 'postsProgress', 'messagesProgress', 'working']),
561
561
  ]);
562
562
  const topicCount = parseInt(global.topicCount, 10);
563
563
  const postCount = parseInt(global.postCount, 10);
564
564
  const messageCount = parseInt(global.messageCount, 10);
565
- const topicsPercent = topicCount ? (pluginData.topicsIndexed / topicCount) * 100 : 0;
566
- const postsPercent = postCount ? (pluginData.postsIndexed / postCount) * 100 : 0;
567
- const messagesPercent = messageCount ? (pluginData.messagesIndexed / messageCount) * 100 : 0;
565
+ const topicsPercent = topicCount ? (pluginData.topicsProgress / topicCount) * 100 : 0;
566
+ const postsPercent = postCount ? (pluginData.postsProgress / postCount) * 100 : 0;
567
+ const messagesPercent = messageCount ? (pluginData.messagesProgress / messageCount) * 100 : 0;
568
568
  return {
569
569
  topicsPercent: Math.max(0, Math.min(100, topicsPercent.toFixed(2))),
570
570
  postsPercent: Math.max(0, Math.min(100, postsPercent.toFixed(2))),
571
571
  messagesPercent: Math.max(0, Math.min(100, messagesPercent.toFixed(2))),
572
- topicsIndexed: topicsPercent >= 100 ? topicCount : Math.max(0, pluginData.topicsIndexed),
573
- postsIndexed: postsPercent >= 100 ? postCount : Math.max(0, pluginData.postsIndexed),
574
- messagesIndexed: messagesPercent >= 100 ? messageCount : Math.max(0, pluginData.messagesIndexed),
575
572
  working: pluginData.working,
576
573
  };
577
574
  }
@@ -599,26 +596,27 @@ socketAdmin.plugins.dbsearch.clearIndex = async function () {
599
596
 
600
597
  async function clearIndex() {
601
598
  await db.setObject('nodebb-plugin-dbsearch', {
599
+ postsProgress: 0,
600
+ topicsProgress: 0,
601
+ messagesProgress: 0,
602
602
  working: 1,
603
603
  });
604
604
 
605
605
  await Promise.all([
606
- clearSet('topics:tid', 'topic'),
607
- clearSet('posts:pid', 'post'),
608
- clearSet('messages:mid', 'chat'),
606
+ clearSet('topics:tid', 'topic', 'topicsProgress'),
607
+ clearSet('posts:pid', 'post', 'postsProgress'),
608
+ clearSet('messages:mid', 'chat', 'messagesProgress'),
609
609
  ]);
610
610
 
611
611
  await db.setObject('nodebb-plugin-dbsearch', {
612
- postsIndexed: 0,
613
- topicsIndexed: 0,
614
- messagesIndexed: 0,
615
612
  working: 0,
616
613
  });
617
614
  }
618
615
 
619
- async function clearSet(set, key) {
616
+ async function clearSet(set, key, progressKey) {
620
617
  await batch.processSortedSet(set, async (ids) => {
621
618
  await searchRemove(key, ids);
619
+ await db.incrObjectFieldBy('nodebb-plugin-dbsearch', progressKey, ids.length);
622
620
  }, {
623
621
  batch: batchSize,
624
622
  });
package/lib/mongo.js CHANGED
@@ -226,3 +226,14 @@ function buildTextQuery(content, matchWords) {
226
226
  return { $search: words.join(' ') };
227
227
  }
228
228
 
229
+ exports.getIndexedTopicCount = async () => {
230
+ return await db.client.collection('searchtopic').estimatedDocumentCount();
231
+ };
232
+
233
+ exports.getIndexedPostCount = async () => {
234
+ return await db.client.collection('searchpost').estimatedDocumentCount();
235
+ };
236
+
237
+ exports.getIndexedChatMessageCount = async () => {
238
+ return await db.client.collection('searchchat').estimatedDocumentCount();
239
+ };
package/lib/postgres.js CHANGED
@@ -164,3 +164,19 @@ exports.chat.search = async (data, limit) => {
164
164
  return [];
165
165
  }
166
166
  };
167
+
168
+
169
+ exports.getIndexedTopicCount = async () => {
170
+ const res = await db.pool.query(`SELECT reltuples::bigint AS estimate FROM pg_class WHERE relname = 'searchtopic'`);
171
+ return res.rows && res.rows[0] ? parseInt(res.rows[0].estimate, 10) : 0;
172
+ };
173
+
174
+ exports.getIndexedPostCount = async () => {
175
+ const res = await db.pool.query(`SELECT reltuples::bigint AS estimate FROM pg_class WHERE relname = 'searchpost'`);
176
+ return res.rows && res.rows[0] ? parseInt(res.rows[0].estimate, 10) : 0;
177
+ };
178
+
179
+ exports.getIndexedChatMessageCount = async () => {
180
+ const res = await db.pool.query(`SELECT reltuples::bigint AS estimate FROM pg_class WHERE relname = 'searchchat'`);
181
+ return res.rows && res.rows[0] ? parseInt(res.rows[0].estimate, 10) : 0;
182
+ };
package/lib/redis.js CHANGED
@@ -86,3 +86,15 @@ exports.chat.search = async (data, limit) => {
86
86
 
87
87
  return await db.chatSearch.query(query, 0, limit - 1);
88
88
  };
89
+
90
+ exports.getIndexedTopicCount = async () => {
91
+ return await db.topicSearch.count('nodebbtopicsearch');
92
+ };
93
+
94
+ exports.getIndexedPostCount = async () => {
95
+ return await db.postSearch.count('nodebbpostsearch');
96
+ };
97
+
98
+ exports.getIndexedChatMessageCount = async () => {
99
+ return await db.chatSearch.count('nodebbchatsearch');
100
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-dbsearch",
3
- "version": "6.3.3",
3
+ "version": "6.3.5",
4
4
  "description": "A Plugin that lets users search posts and topics",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -20,7 +20,7 @@
20
20
  "license": "BSD-2-Clause",
21
21
  "dependencies": {
22
22
  "lodash": "4.17.21",
23
- "redisearch": "^2.0.0"
23
+ "redisearch": "^2.0.1"
24
24
  },
25
25
  "devDependencies": {
26
26
  "eslint": "^9.25.1",
package/public/admin.js CHANGED
@@ -78,6 +78,11 @@ define('admin/plugins/dbsearch', [
78
78
  };
79
79
 
80
80
  function startProgress() {
81
+ $('#topics-indexed').text(0);
82
+ $('#posts-indexed').text(0);
83
+ $('#messages-indexed').text(0);
84
+ $('.progress-bar').css('width', '0%').text('0%');
85
+ $('.progress').removeClass('invisible');
81
86
  clearProgress();
82
87
  intervalId = setInterval(checkProgress, 1000);
83
88
  }
@@ -85,6 +90,7 @@ define('admin/plugins/dbsearch', [
85
90
  function clearProgress() {
86
91
  if (intervalId) {
87
92
  clearInterval(intervalId);
93
+ $('.progress').addClass('invisible');
88
94
  intervalId = 0;
89
95
  }
90
96
  }
@@ -96,27 +102,31 @@ define('admin/plugins/dbsearch', [
96
102
  return alerts.error(err);
97
103
  }
98
104
 
105
+ $('.topic-progress').css('width', progress.topicsPercent + '%').text(progress.topicsPercent + '%');
106
+ $('.post-progress').css('width', progress.postsPercent + '%').text(progress.postsPercent + '%');
107
+ $('.message-progress').css('width', progress.messagesPercent + '%').text(progress.messagesPercent + '%');
108
+
99
109
  var working = parseInt(progress.working, 10);
100
110
  if (!working) {
101
111
  clearInterval(intervalId);
102
112
  $('#reindex').removeAttr('disabled');
113
+ $('#clear-index').removeAttr('disabled');
114
+ setTimeout(() => {
115
+ $('.progress').addClass('invisible');
116
+ }, 2000);
117
+
118
+ $.getJSON(config.relative_path + '/api/admin/plugins/dbsearch', function (data) {
119
+ $('#topics-indexed').text(data.topicsIndexed);
120
+ $('#posts-indexed').text(data.postsIndexed);
121
+ $('#messages-indexed').text(data.messagesIndexed);
122
+ });
103
123
  } else {
104
124
  $('#reindex').attr('disabled', true);
125
+ $('#clear-index').attr('disabled', true);
126
+ $('.progress').removeClass('invisible');
105
127
  }
106
128
 
107
129
  $('#work-in-progress').toggleClass('hidden', !working);
108
-
109
- if (progress.topicsPercent >= 100 && progress.postsPercent >= 100) {
110
- progress.topicsPercent = 100;
111
- progress.postsPercent = 100;
112
- }
113
-
114
- $('#topics-indexed').text(progress.topicsIndexed);
115
- $('#posts-indexed').text(progress.postsIndexed);
116
- $('#messages-indexed').text(progress.messagesIndexed);
117
- $('.topic-progress').css('width', progress.topicsPercent + '%').text(progress.topicsPercent + '%');
118
- $('.post-progress').css('width', progress.postsPercent + '%').text(progress.postsPercent + '%');
119
- $('.message-progress').css('width', progress.messagesPercent + '%').text(progress.messagesPercent + '%');
120
130
  });
121
131
  }
122
132
 
@@ -9,27 +9,27 @@
9
9
  <div class="col-6">
10
10
  <div class="mb-3">
11
11
  <div class="alert alert-info">
12
- Topics Indexed: <strong id="topics-indexed">{topicsIndexed}</strong> / <strong>{topicCount}</strong>
12
+ Topics Indexed: <strong id="topics-indexed">{topicsIndexed}</strong> <i class="fa fa-circle-question" title="Deleted topics are not indexed" data-bs-toggle="tooltip"></i>
13
13
  </div>
14
14
 
15
- <div class="progress" style="height:24px;">
15
+ <div class="progress {{{ if !working }}}invisible{{{ end }}}" style="height:24px;">
16
16
  <div class="topic-progress progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:{progressData.topicsPercent}%;min-width: 2em;">{progressData.topicsPercent}%</div>
17
17
  </div>
18
18
  </div>
19
19
  <div class="mb-3">
20
20
  <div class="alert alert-info">
21
- Posts Indexed: <strong id="posts-indexed">{postsIndexed}</strong> / <strong>{postCount}</strong>
21
+ Posts Indexed: <strong id="posts-indexed">{postsIndexed}</strong> <i class="fa fa-circle-question" title="Deleted posts are not indexed" data-bs-toggle="tooltip"></i>
22
22
  </div>
23
- <div class="progress" style="height:24px;">
23
+ <div class="progress {{{ if !working }}}invisible{{{ end }}}" style="height:24px;">
24
24
  <div class="post-progress progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:{progressData.postsPercent}%;min-width: 2em;">{progressData.postsPercent}%</div>
25
25
  </div>
26
26
  </div>
27
27
 
28
28
  <div class="mb-3">
29
29
  <div class="alert alert-info">
30
- Messages Indexed: <strong id="messages-indexed">{messagesIndexed}</strong> / <strong>{messageCount}</strong>
30
+ Messages Indexed: <strong id="messages-indexed">{messagesIndexed}</strong> <i class="fa fa-circle-question" title="Deleted messages are not indexed" data-bs-toggle="tooltip"></i>
31
31
  </div>
32
- <div class="progress" style="height:24px;">
32
+ <div class="progress {{{ if !working }}}invisible{{{ end }}}" style="height:24px;">
33
33
  <div class="message-progress progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:{progressData.messagesPercent}%;min-width: 2em;">{progressData.messagesPercent}%</div>
34
34
  </div>
35
35
  </div>
@@ -23,6 +23,5 @@ module.exports = {
23
23
  } catch (err) {
24
24
  winston.error(err.stack);
25
25
  }
26
- await plugin.reindex();
27
26
  },
28
27
  };