nodebb-plugin-dbsearch 6.3.2 → 6.3.4

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/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
  });
@@ -274,6 +277,7 @@ async function reIndexTopics() {
274
277
  async function topicsSave(topics) {
275
278
  topics = topics.filter(
276
279
  t => t && utils.isNumber(t.tid) && parseInt(t.deleted, 10) !== 1 &&
280
+ utils.isNumber(t.cid) &&
277
281
  !pluginConfig.excludeCategories.includes(String(t.cid))
278
282
  );
279
283
 
@@ -305,7 +309,6 @@ async function topicsSave(topics) {
305
309
 
306
310
  const result = await plugins.hooks.fire('filter:search.indexTopics', { data: data, tids: tids, topics: topics });
307
311
  await db.searchIndex('topic', result.data, result.tids);
308
- await db.incrObjectFieldBy('nodebb-plugin-dbsearch', 'topicsIndexed', result.tids.length);
309
312
  }
310
313
 
311
314
  async function reIndexPosts() {
@@ -322,6 +325,7 @@ async function reIndexPosts() {
322
325
  });
323
326
  postData = postData.filter(post => tidToTopic[post.tid].deleted !== 1);
324
327
  await postsSave(postData);
328
+ await db.incrObjectFieldBy('nodebb-plugin-dbsearch', 'postsProgress', pids.length);
325
329
  }, {
326
330
  batch: batchSize,
327
331
  });
@@ -330,6 +334,7 @@ async function reIndexPosts() {
330
334
  async function postsSave(posts) {
331
335
  posts = posts.filter(
332
336
  p => p && utils.isNumber(p.pid) && parseInt(p.deleted, 10) !== 1 &&
337
+ utils.isNumber(p.cid) &&
333
338
  !pluginConfig.excludeCategories.includes(String(p.cid))
334
339
  );
335
340
 
@@ -361,7 +366,6 @@ async function postsSave(posts) {
361
366
 
362
367
  const result = await plugins.hooks.fire('filter:search.indexPosts', { data: data, pids: pids, posts: posts });
363
368
  await db.searchIndex('post', result.data, result.pids);
364
- await db.incrObjectFieldBy('nodebb-plugin-dbsearch', 'postsIndexed', result.pids.length);
365
369
  }
366
370
 
367
371
  async function reIndexMessages() {
@@ -369,13 +373,16 @@ async function reIndexMessages() {
369
373
  let messageData = await messaging.getMessagesFields(mids, ['mid', 'content', 'roomId', 'fromuid', 'deleted', 'system']);
370
374
  messageData = messageData.filter(p => p && p.deleted !== 1 && p.system !== 1);
371
375
  await messagesSave(messageData);
376
+ await db.incrObjectFieldBy('nodebb-plugin-dbsearch', 'messagesProgress', mids.length);
372
377
  }, {
373
378
  batch: batchSize,
374
379
  });
375
380
  }
376
381
 
377
382
  async function messagesSave(msgs) {
378
- 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
+ );
379
386
 
380
387
  let data = msgs.map((msgData) => {
381
388
  const indexData = {};
@@ -402,19 +409,11 @@ async function messagesSave(msgs) {
402
409
 
403
410
  const result = await plugins.hooks.fire('filter:search.indexMessages', { data: data, mids: mids, messages: msgs });
404
411
  await searchModule.chat.index(result.data, result.mids);
405
- await db.incrObjectFieldBy('nodebb-plugin-dbsearch', 'messagesIndexed', result.mids.length);
406
412
  }
407
413
 
408
414
  async function searchRemove(key, ids) {
409
415
  ids = ids.filter(id => id && utils.isNumber(id));
410
416
  await db.searchRemove(key, ids);
411
- if (key === 'topic') {
412
- await db.incrObjectFieldBy('nodebb-plugin-dbsearch', 'topicsIndexed', -ids.length);
413
- } else if (key === 'post') {
414
- await db.incrObjectFieldBy('nodebb-plugin-dbsearch', 'postsIndexed', -ids.length);
415
- } else if (key === 'chat') {
416
- await db.incrObjectFieldBy('nodebb-plugin-dbsearch', 'messagesIndexed', -ids.length);
417
- }
418
417
  }
419
418
 
420
419
  async function reIndexTids(tids) {
@@ -466,6 +465,14 @@ async function reIndexPids(pids, topic) {
466
465
 
467
466
  async function renderAdmin(req, res) {
468
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;
469
476
  results.plugin.progressData = await getProgress();
470
477
  results.plugin.title = 'DB Search';
471
478
  res.render('admin/plugins/dbsearch', results.plugin);
@@ -496,14 +503,12 @@ socketAdmin.plugins.dbsearch.checkProgress = async function () {
496
503
 
497
504
  async function getPluginData() {
498
505
  const data = await db.getObject('nodebb-plugin-dbsearch') || {};
499
- data.topicsIndexed = parseInt(data.topicsIndexed, 10) || 0;
500
- data.postsIndexed = parseInt(data.postsIndexed, 10) || 0;
501
- data.messagesIndexed = parseInt(data.messagesIndexed, 10) || 0;
506
+
502
507
  data.excludeCategories = data.excludeCategories || '[]';
503
508
  data.postLimit = data.postLimit || defaultPostLimit;
504
509
  data.topicLimit = data.topicLimit || defaultTopicLimit;
505
510
  data.indexLanguage = data.indexLanguage || 'en';
506
- data.working = data.working || 0;
511
+ data.working = parseInt(data.working, 10) || 0;
507
512
 
508
513
  try {
509
514
  data.excludeCategories = JSON.parse(data.excludeCategories);
@@ -535,9 +540,6 @@ async function getGlobalAndPluginData() {
535
540
  plugin.messageCount = parseInt(global.messageCount, 10);
536
541
  plugin.topicLimit = plugin.topicLimit || defaultTopicLimit;
537
542
  plugin.postLimit = plugin.postLimit || defaultPostLimit;
538
- plugin.topicsIndexed = plugin.topicsIndexed > plugin.topicCount ? plugin.topicCount : plugin.topicsIndexed;
539
- plugin.postsIndexed = plugin.postsIndexed > plugin.postCount ? plugin.postCount : plugin.postsIndexed;
540
- plugin.messagesIndexed = plugin.messagesIndexed > plugin.messageCount ? plugin.messageCount : plugin.messagesIndexed;
541
543
  plugin.languageSupported = languageSupported;
542
544
  plugin.languages = languages;
543
545
  plugin.indexLanguage = plugin.indexLanguage || 'en';
@@ -555,21 +557,18 @@ async function getGlobalAndPluginData() {
555
557
  async function getProgress() {
556
558
  const [global, pluginData] = await Promise.all([
557
559
  db.getObjectFields('global', ['topicCount', 'postCount', 'messageCount']),
558
- getPluginData(),
560
+ db.getObjectFields('nodebb-plugin-dbsearch', ['topicsProgress', 'postsProgress', 'messagesProgress', 'working']),
559
561
  ]);
560
562
  const topicCount = parseInt(global.topicCount, 10);
561
563
  const postCount = parseInt(global.postCount, 10);
562
564
  const messageCount = parseInt(global.messageCount, 10);
563
- const topicsPercent = topicCount ? (pluginData.topicsIndexed / topicCount) * 100 : 0;
564
- const postsPercent = postCount ? (pluginData.postsIndexed / postCount) * 100 : 0;
565
- 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;
566
568
  return {
567
569
  topicsPercent: Math.max(0, Math.min(100, topicsPercent.toFixed(2))),
568
570
  postsPercent: Math.max(0, Math.min(100, postsPercent.toFixed(2))),
569
571
  messagesPercent: Math.max(0, Math.min(100, messagesPercent.toFixed(2))),
570
- topicsIndexed: topicsPercent >= 100 ? topicCount : Math.max(0, pluginData.topicsIndexed),
571
- postsIndexed: postsPercent >= 100 ? postCount : Math.max(0, pluginData.postsIndexed),
572
- messagesIndexed: messagesPercent >= 100 ? messageCount : Math.max(0, pluginData.messagesIndexed),
573
572
  working: pluginData.working,
574
573
  };
575
574
  }
@@ -597,26 +596,27 @@ socketAdmin.plugins.dbsearch.clearIndex = async function () {
597
596
 
598
597
  async function clearIndex() {
599
598
  await db.setObject('nodebb-plugin-dbsearch', {
599
+ postsProgress: 0,
600
+ topicsProgress: 0,
601
+ messagesProgress: 0,
600
602
  working: 1,
601
603
  });
602
604
 
603
605
  await Promise.all([
604
- clearSet('topics:tid', 'topic'),
605
- clearSet('posts:pid', 'post'),
606
- clearSet('messages:mid', 'chat'),
606
+ clearSet('topics:tid', 'topic', 'topicsProgress'),
607
+ clearSet('posts:pid', 'post', 'postsProgress'),
608
+ clearSet('messages:mid', 'chat', 'messagesProgress'),
607
609
  ]);
608
610
 
609
611
  await db.setObject('nodebb-plugin-dbsearch', {
610
- postsIndexed: 0,
611
- topicsIndexed: 0,
612
- messagesIndexed: 0,
613
612
  working: 0,
614
613
  });
615
614
  }
616
615
 
617
- async function clearSet(set, key) {
616
+ async function clearSet(set, key, progressKey) {
618
617
  await batch.processSortedSet(set, async (ids) => {
619
618
  await searchRemove(key, ids);
619
+ await db.incrObjectFieldBy('nodebb-plugin-dbsearch', progressKey, ids.length);
620
620
  }, {
621
621
  batch: batchSize,
622
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.2",
3
+ "version": "6.3.4",
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>