@vegan-friendly/strapi-plugin-elasticsearch 0.2.9 → 0.3.0
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/dist/package.json +2 -2
- package/dist/server/content-types/index.d.ts +4 -0
- package/dist/server/content-types/tasks.d.ts +4 -0
- package/dist/server/content-types/tasks.js +5 -1
- package/dist/server/index.d.ts +6 -2
- package/dist/server/services/index.d.ts +2 -2
- package/dist/server/services/perform-indexing.d.ts +1 -1
- package/dist/server/services/perform-indexing.js +11 -9
- package/dist/server/services/schedule-indexing.d.ts +1 -1
- package/dist/server/services/schedule-indexing.js +4 -2
- package/dist/server/services/virtual-collections-indexer.js +23 -11
- package/dist/server/services/virtual-collections-registry.js +0 -1
- package/dist/server/types/virtual-collections.type.d.ts +0 -5
- package/package.json +3 -3
package/dist/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vegan-friendly/strapi-plugin-elasticsearch",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.3.0",
|
4
4
|
"description": "A Strapi plugin to enable using Elasticsearch with Strapi CMS.",
|
5
5
|
"homepage": "https://github.com/vegan-friendly/strapi-plugin-elasticsearch",
|
6
6
|
"strapi": {
|
@@ -54,7 +54,7 @@
|
|
54
54
|
}
|
55
55
|
],
|
56
56
|
"engines": {
|
57
|
-
"node": ">=16.0.0
|
57
|
+
"node": ">=16.0.0",
|
58
58
|
"npm": ">=6.0.0"
|
59
59
|
},
|
60
60
|
"license": "MIT",
|
@@ -30,10 +30,14 @@ exports.default = {
|
|
30
30
|
},
|
31
31
|
indexing_status: {
|
32
32
|
type: 'enumeration',
|
33
|
-
enum: ['to-be-done', 'in-progress', 'done'],
|
33
|
+
enum: ['to-be-done', 'in-progress', 'done', 'failed'],
|
34
34
|
required: true,
|
35
35
|
default: 'to-be-done',
|
36
36
|
},
|
37
|
+
error_message: {
|
38
|
+
type: 'string',
|
39
|
+
required: false,
|
40
|
+
},
|
37
41
|
full_site_indexing: {
|
38
42
|
type: 'boolean',
|
39
43
|
},
|
package/dist/server/index.d.ts
CHANGED
@@ -142,7 +142,7 @@ declare const _default: {
|
|
142
142
|
recordId: any;
|
143
143
|
}): Promise<void>;
|
144
144
|
getItemsPendingToBeIndexed(): Promise<any>;
|
145
|
-
markIndexingTaskComplete(recId: any): Promise<void>;
|
145
|
+
markIndexingTaskComplete(recId: any, error?: string | null): Promise<void>;
|
146
146
|
markIndexingTaskInProgress(recId: any): Promise<void>;
|
147
147
|
getFullIndexingInProgress(): Promise<any>;
|
148
148
|
};
|
@@ -152,7 +152,7 @@ declare const _default: {
|
|
152
152
|
indexer: ({ strapi }: {
|
153
153
|
strapi: any;
|
154
154
|
}) => {
|
155
|
-
rebuildIndex(
|
155
|
+
rebuildIndex(task?: any): Promise<boolean>;
|
156
156
|
indexCollection(collectionName: any, indexName?: string | null): Promise<number>;
|
157
157
|
indexPendingData(): Promise<boolean>;
|
158
158
|
};
|
@@ -215,6 +215,10 @@ declare const _default: {
|
|
215
215
|
required: boolean;
|
216
216
|
default: string;
|
217
217
|
};
|
218
|
+
error_message: {
|
219
|
+
type: string;
|
220
|
+
required: boolean;
|
221
|
+
};
|
218
222
|
full_site_indexing: {
|
219
223
|
type: string;
|
220
224
|
};
|
@@ -38,7 +38,7 @@ declare const _default: {
|
|
38
38
|
recordId: any;
|
39
39
|
}): Promise<void>;
|
40
40
|
getItemsPendingToBeIndexed(): Promise<any>;
|
41
|
-
markIndexingTaskComplete(recId: any): Promise<void>;
|
41
|
+
markIndexingTaskComplete(recId: any, error?: string | null): Promise<void>;
|
42
42
|
markIndexingTaskInProgress(recId: any): Promise<void>;
|
43
43
|
getFullIndexingInProgress(): Promise<any>;
|
44
44
|
};
|
@@ -48,7 +48,7 @@ declare const _default: {
|
|
48
48
|
indexer: ({ strapi }: {
|
49
49
|
strapi: any;
|
50
50
|
}) => {
|
51
|
-
rebuildIndex(
|
51
|
+
rebuildIndex(task?: any): Promise<boolean>;
|
52
52
|
indexCollection(collectionName: any, indexName?: string | null): Promise<number>;
|
53
53
|
indexPendingData(): Promise<boolean>;
|
54
54
|
};
|
@@ -1,7 +1,7 @@
|
|
1
1
|
declare const _default: ({ strapi }: {
|
2
2
|
strapi: any;
|
3
3
|
}) => {
|
4
|
-
rebuildIndex(
|
4
|
+
rebuildIndex(task?: any): Promise<boolean>;
|
5
5
|
indexCollection(collectionName: any, indexName?: string | null): Promise<number>;
|
6
6
|
indexPendingData(): Promise<boolean>;
|
7
7
|
};
|
@@ -1,7 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.default = ({ strapi }) => ({
|
4
|
-
async rebuildIndex(
|
4
|
+
async rebuildIndex(task = null) {
|
5
5
|
const helper = strapi.plugins['elasticsearch'].services.helper;
|
6
6
|
const esInterface = strapi.plugins['elasticsearch'].services.esInterface;
|
7
7
|
const scheduleIndexingService = strapi.plugins['elasticsearch'].services.scheduleIndexing;
|
@@ -9,6 +9,7 @@ exports.default = ({ strapi }) => ({
|
|
9
9
|
const logIndexingService = strapi.plugins['elasticsearch'].services.logIndexing;
|
10
10
|
const virtualCollectionsIndexer = strapi.plugins['elasticsearch'].services['virtualCollectionsIndexer'];
|
11
11
|
const virtualCollectionsRegistry = strapi.plugins['elasticsearch'].services['virtualCollectionsRegistry'];
|
12
|
+
let taskError = null;
|
12
13
|
try {
|
13
14
|
console.log('strapi-plugin-elasticsearch : Request to rebuild the index received.');
|
14
15
|
const fullIndexingInProgress = await scheduleIndexingService.getFullIndexingInProgress();
|
@@ -35,19 +36,19 @@ exports.default = ({ strapi }) => ({
|
|
35
36
|
}
|
36
37
|
//Step 2 : Index all the stuff on this new index
|
37
38
|
console.log('strapi-plugin-elasticsearch : Starting to index all data into the new index.');
|
38
|
-
if (
|
39
|
-
|
39
|
+
if (task == null) {
|
40
|
+
task = await scheduleIndexingService.addFullSiteIndexingTask();
|
40
41
|
}
|
41
|
-
if (
|
42
|
-
await scheduleIndexingService.markIndexingTaskInProgress(
|
42
|
+
if (task?.id) {
|
43
|
+
await scheduleIndexingService.markIndexingTaskInProgress(task.id);
|
43
44
|
let entitiesIndexed = 0;
|
44
45
|
for (let r = 0; r < cols.length; r++) {
|
45
46
|
entitiesIndexed += await this.indexCollection(cols[r], newIndexName);
|
46
47
|
}
|
47
48
|
// Indexing the virtual collections
|
48
|
-
console.log('strapi-plugin-elasticsearch : Starting to index virtual collections. task id : ',
|
49
|
+
console.log('strapi-plugin-elasticsearch : Starting to index virtual collections. task id : ', task.id);
|
49
50
|
const virtualEntriesIndexed = await virtualCollectionsIndexer.reindexAll(newIndexName);
|
50
|
-
await scheduleIndexingService.markIndexingTaskComplete(
|
51
|
+
await scheduleIndexingService.markIndexingTaskComplete(task.id);
|
51
52
|
console.log('strapi-plugin-elasticsearch : Indexing of data into the new index complete.');
|
52
53
|
//Step 4 : Move the alias to this new index
|
53
54
|
await esInterface.attachAliasToIndex(newIndexName);
|
@@ -64,14 +65,15 @@ exports.default = ({ strapi }) => ({
|
|
64
65
|
}
|
65
66
|
}
|
66
67
|
catch (err) {
|
68
|
+
taskError = err.message || String(err);
|
67
69
|
console.log('strapi-plugin-elasticsearch : searchController : An error was encountered while re-indexing.');
|
68
70
|
console.log(err);
|
69
71
|
await logIndexingService.recordIndexingFail(err);
|
70
72
|
throw err;
|
71
73
|
}
|
72
74
|
finally {
|
73
|
-
if (
|
74
|
-
await scheduleIndexingService.markIndexingTaskComplete(
|
75
|
+
if (task?.id) {
|
76
|
+
await scheduleIndexingService.markIndexingTaskComplete(task.id, taskError);
|
75
77
|
}
|
76
78
|
}
|
77
79
|
},
|
@@ -14,7 +14,7 @@ declare const _default: ({ strapi }: {
|
|
14
14
|
recordId: any;
|
15
15
|
}): Promise<void>;
|
16
16
|
getItemsPendingToBeIndexed(): Promise<any>;
|
17
|
-
markIndexingTaskComplete(recId: any): Promise<void>;
|
17
|
+
markIndexingTaskComplete(recId: any, error?: string | null): Promise<void>;
|
18
18
|
markIndexingTaskInProgress(recId: any): Promise<void>;
|
19
19
|
getFullIndexingInProgress(): Promise<any>;
|
20
20
|
};
|
@@ -52,10 +52,12 @@ exports.default = ({ strapi }) => ({
|
|
52
52
|
});
|
53
53
|
return entries;
|
54
54
|
},
|
55
|
-
async markIndexingTaskComplete(recId) {
|
55
|
+
async markIndexingTaskComplete(recId, error = null) {
|
56
|
+
const status = error ? 'failed' : 'done';
|
56
57
|
const entries = await strapi.entityService.update('plugin::elasticsearch.task', recId, {
|
57
58
|
data: {
|
58
|
-
indexing_status:
|
59
|
+
indexing_status: status,
|
60
|
+
error_message: error,
|
59
61
|
},
|
60
62
|
});
|
61
63
|
},
|
@@ -24,7 +24,9 @@ exports.default = ({ strapi }) => {
|
|
24
24
|
try {
|
25
25
|
const results = await collection.extractByIds([itemId]);
|
26
26
|
if (!results || !Array.isArray(results) || results.length === 0) {
|
27
|
-
|
27
|
+
// item does not exit - delete it from index
|
28
|
+
await this.deleteItem(collectionName, itemId);
|
29
|
+
strapi.log.debug(`Deleted virtual item: ${collectionName}:${itemId}`);
|
28
30
|
return null;
|
29
31
|
}
|
30
32
|
const itemData = results[0];
|
@@ -58,9 +60,11 @@ exports.default = ({ strapi }) => {
|
|
58
60
|
async reindex(collection) {
|
59
61
|
const collectionName = collection.collectionName;
|
60
62
|
const privateIndexAlias = collection.indexAlias;
|
63
|
+
const pageSize = 100;
|
61
64
|
const helper = getHelperService();
|
62
65
|
let timestamp = Date.now();
|
63
66
|
let indexName = '';
|
67
|
+
let errors = 0;
|
64
68
|
try {
|
65
69
|
const esInterface = getElasticsearchService();
|
66
70
|
if (privateIndexAlias) {
|
@@ -75,7 +79,16 @@ exports.default = ({ strapi }) => {
|
|
75
79
|
let totalIndexed = 0;
|
76
80
|
const pageLimit = 10000;
|
77
81
|
while (page <= pageLimit) {
|
78
|
-
|
82
|
+
let pageData;
|
83
|
+
try {
|
84
|
+
pageData = await collection.extractData(page, pageSize);
|
85
|
+
}
|
86
|
+
catch (error) {
|
87
|
+
strapi.log.error(`Error extracting data for page ${page} of ${collectionName}: ${error.message}`);
|
88
|
+
errors += pageSize;
|
89
|
+
page++;
|
90
|
+
continue;
|
91
|
+
}
|
79
92
|
strapi.log.debug(`Extracted ${pageData.length} items from ${collectionName} for page ${page}`);
|
80
93
|
if (!Array.isArray(pageData) || pageData.length === 0) {
|
81
94
|
break;
|
@@ -97,12 +110,18 @@ exports.default = ({ strapi }) => {
|
|
97
110
|
operations.push({ itemId, itemData });
|
98
111
|
}
|
99
112
|
if (operations.length > 0) {
|
100
|
-
await Promise.all(operations.map((op) => esInterface.indexDataToSpecificIndex(op, indexName))
|
113
|
+
await Promise.all(operations.map((op) => esInterface.indexDataToSpecificIndex(op, indexName).catch((err) => {
|
114
|
+
strapi.log.error(`Failed to index item ${op.itemId} in ${collectionName}: ${err}`);
|
115
|
+
errors++;
|
116
|
+
})));
|
101
117
|
}
|
102
118
|
totalIndexed += pageData.length;
|
103
119
|
prevPageData = pageData;
|
104
120
|
page++;
|
105
121
|
}
|
122
|
+
if (errors > 0) {
|
123
|
+
throw new Error(`Failed to index ${errors} of ${totalIndexed} items for virtual collection ${collectionName}. Errors were logged. Alias was not updated. took ${(0, humanize_duration_1.default)(Date.now() - timestamp)}`);
|
124
|
+
}
|
106
125
|
strapi.log.info(`Reindexed ${totalIndexed} items for virtual collection: ${collectionName}. took ${(0, humanize_duration_1.default)(Date.now() - timestamp)}. now updating alias.`);
|
107
126
|
if (privateIndexAlias) {
|
108
127
|
timestamp = Date.now();
|
@@ -138,14 +157,7 @@ exports.default = ({ strapi }) => {
|
|
138
157
|
const idsToReindex = await trigger.getIdsToReindex(result);
|
139
158
|
// Reindex each item
|
140
159
|
for (const id of idsToReindex) {
|
141
|
-
|
142
|
-
if (isDelete) {
|
143
|
-
//delete the item from the index, if the item being delete is the one being reindexed
|
144
|
-
await this.deleteItem(collection.collectionName, id);
|
145
|
-
}
|
146
|
-
else {
|
147
|
-
await this.indexItem(collection.collectionName, id);
|
148
|
-
}
|
160
|
+
await this.indexItem(collection.collectionName, id);
|
149
161
|
}
|
150
162
|
}
|
151
163
|
},
|
@@ -45,11 +45,6 @@ export type VirtualCollectionConfig = {
|
|
45
45
|
* @returns ids of the items to be reindexed.
|
46
46
|
*/
|
47
47
|
getIdsToReindex: GetIdsToIndexFunction;
|
48
|
-
/**
|
49
|
-
* if true, and the trigger is a delete event, the item of the virtual collection will be deleted as well if the id returned from getIdsToReindex match.
|
50
|
-
* defaults to false.
|
51
|
-
*/
|
52
|
-
alsoTriggerDelete?: boolean;
|
53
48
|
}>;
|
54
49
|
/**
|
55
50
|
* Optional schema to be sent to Elasticsearch when creating the index.
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vegan-friendly/strapi-plugin-elasticsearch",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.3.0",
|
4
4
|
"description": "A Strapi plugin to enable using Elasticsearch with Strapi CMS.",
|
5
5
|
"homepage": "https://github.com/vegan-friendly/strapi-plugin-elasticsearch",
|
6
6
|
"strapi": {
|
@@ -54,7 +54,7 @@
|
|
54
54
|
}
|
55
55
|
],
|
56
56
|
"engines": {
|
57
|
-
"node": ">=16.0.0
|
57
|
+
"node": ">=16.0.0",
|
58
58
|
"npm": ">=6.0.0"
|
59
59
|
},
|
60
60
|
"license": "MIT",
|
@@ -64,4 +64,4 @@
|
|
64
64
|
"ts-node": "^10.9.2",
|
65
65
|
"typescript": "^5.8.3"
|
66
66
|
}
|
67
|
-
}
|
67
|
+
}
|