Skip to content

Commit ffcf43c

Browse files
Merge #916
916: Handle multiple index names in strapi config r=brunoocasali a=L-Weisz # Pull Request ## Related issue Fixes #651 ## What does this PR do? This Pull Request introduces the capability to associate a single collection with multiple index names within Strapi's configuration. Previously, the indexName parameter was limited to a single string value, specifying one index per collection. Now, indexName can be defined as an array, enabling a collection to be indexed under multiple names simultaneously. For example, the configuration can now be specified as: Before: indexName: "my_restaurant" After: indexName: "my_restaurant" (after review, found a way to avoid the breaking change) After: indexName: ["my_restaurant"] After: indexName: ["my_restaurant", "all_restaurants"] Additionally, this update includes the introduction of new tests to ensure that the expanded functionality does not disrupt existing features. An existing test was also corrected. Important Changes: **Limitation:** While indexName can now accept multiple values, all other configuration attributes remain uniform across the specified indexes. This means that any update to one index will apply identically to all indexes associated with a given collection, reflecting the same settings and data. This enhancement provides greater flexibility in managing index names for collections within Strapi, streamlining the process of data organization and retrieval across multiple indexes. ### Result ![image](https://github.com/meilisearch/strapi-plugin-meilisearch/assets/117728108/33d6c8aa-8558-40d0-8fa4-14b3551811d1) ![image](https://github.com/meilisearch/strapi-plugin-meilisearch/assets/117728108/3baee28b-23a6-4766-a828-ebf52175c895) ## PR checklist Please check if your PR fulfills the following requirements: - [x] Does this PR fix an existing issue, or have you listed the changes applied in the PR description (and why they are needed)? - [x] Have you read the contributing guidelines? - [x] Have you made sure that the title is accurate and descriptive of the changes? Thank you so much for contributing to Meilisearch! Co-authored-by: Leah Weisz <[email protected]> Co-authored-by: L-Weisz <[email protected]>
2 parents 4a9d0f0 + 406a9a2 commit ffcf43c

File tree

11 files changed

+801
-163
lines changed

11 files changed

+801
-163
lines changed

README.md

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,11 @@ Settings:
217217

218218
By default, when indexing a content-type in Meilisearch, the index in Meilisearch has the same name as the content-type. This behavior can be changed by setting the `indexName` property in the configuration file of the plugin.
219219

220-
**Example:**
220+
To link a single collection to multiple indexes, you can assign an array of index names to the `indexName` property.
221221

222-
In the following example, the `restaurant` content-type in Meilisearch is called `my_restaurant` instead of the default `restaurant`.
222+
**Example 1: Linking a Single Collection to a Single Index**
223+
224+
In the following examples, the `restaurant` content-type in Meilisearch is called `my_restaurant` instead of the default `restaurant`.
223225

224226
```js
225227
// config/plugins.js
@@ -236,6 +238,21 @@ module.exports = () => ({
236238
})
237239
```
238240

241+
```js
242+
// config/plugins.js
243+
244+
module.exports = () => ({
245+
//...
246+
meilisearch: {
247+
config: {
248+
restaurant: {
249+
indexName: ["my_restaurants"],
250+
}
251+
}
252+
}
253+
})
254+
```
255+
239256
It is possible to bind multiple content-types to the same index. They all have to share the same `indexName`.
240257

241258
For example if `shoes` and `shirts` should be bound to the same index, they must have the same `indexName` in the plugin configuration:
@@ -248,10 +265,10 @@ module.exports = () => ({
248265
meilisearch: {
249266
config: {
250267
shirts: {
251-
indexName: 'products',
268+
indexName: ['products'],
252269
},
253270
shoes: {
254-
indexName: 'products',
271+
indexName: ['products'],
255272
},
256273
},
257274
},
@@ -260,6 +277,25 @@ module.exports = () => ({
260277

261278
Now, on each entry addition from both `shoes` and `shirts` the entry is added in the `product` index of Meilisearch.
262279

280+
**Example 2: Linking a Single Collection to Multiple Indexes**
281+
282+
Suppose you want the `restaurant` content-type to be indexed under both `my_restaurants` and `all_food_places` indexes in Meilisearch. You can achieve this by setting the `indexName` property to an array containing both index names, as shown in the configuration below:
283+
284+
```js
285+
// config/plugins.js
286+
287+
module.exports = () => ({
288+
//...
289+
meilisearch: {
290+
config: {
291+
restaurant: {
292+
indexName: ['my_restaurants', 'all_food_places'],
293+
}
294+
}
295+
}
296+
})
297+
```
298+
263299

264300
**disclaimer**
265301

playground/config/plugins.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ module.exports = ({ env }) => ({
1515
categories: entry.categories.map(category => category.name)
1616
};
1717
},
18-
indexName: "my_restaurant",
18+
indexName: ["my_restaurant"],
1919
settings: {
2020
"searchableAttributes": ["*"]
2121
}
2222
},
2323
"about-us": {
24-
indexName: "content",
24+
indexName: ["content"],
2525
},
2626
homepage: {
27-
indexName: "content",
27+
indexName: ["content"],
2828
},
2929
// host: "http://localhost:7700",
3030
// apiKey: "masterKey"

resources/custom-index-name/custom-index-name.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
// `shirts` and `pants` will be indexed in the same `products` index.
2+
// `tops` will also be indexed in a separate `tops` index.
23
module.exports = () => ({
34
//...
45
meilisearch: {
56
config: {
67
shirts: {
7-
indexName: 'products',
8+
indexName: ['products', 'tops'],
89
},
910
pants: {
10-
indexName: 'products',
11+
indexName: ['products'],
1112
},
1213
},
1314
},

server/__mocks__/strapi.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ function createStrapiMock({
3939
ApiKeyIsFromConfigFile: true,
4040
HostIsFromConfigFile: true,
4141
}),
42+
getIndexedContentTypes: () => [
43+
'api::restaurant.restaurant',
44+
'api::about.about',
45+
],
4246
actionInBatches: mockActionInBatches,
4347
addIndexedContentType: mockAddIndexedContentType,
4448
subscribeContentType: () => {

server/__tests__/configuration-validation.test.js

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,50 @@ describe('Test plugin configuration', () => {
122122
expect(strapiMock.log.warn).toHaveBeenCalledTimes(0)
123123
expect(strapiMock.log.error).toHaveBeenCalledTimes(1)
124124
expect(strapiMock.log.error).toHaveBeenCalledWith(
125-
'The "indexName" option of "restaurant" should be a non-empty string',
125+
'The "indexName" option of "restaurant" should be a non-empty string or an array of non-empty strings',
126126
)
127127
})
128128

129129
test('Test indexName with non-empty string', async () => {
130130
validatePluginConfig({
131131
restaurant: {
132-
indexName: 'hello',
132+
indexName: 'validName',
133+
},
134+
})
135+
expect(strapiMock.log.warn).toHaveBeenCalledTimes(0)
136+
expect(strapiMock.log.error).toHaveBeenCalledTimes(0)
137+
})
138+
139+
test('Test indexName with empty array', async () => {
140+
validatePluginConfig({
141+
restaurant: {
142+
indexName: [],
143+
},
144+
})
145+
expect(strapiMock.log.warn).toHaveBeenCalledTimes(0)
146+
expect(strapiMock.log.error).toHaveBeenCalledTimes(1)
147+
expect(strapiMock.log.error).toHaveBeenCalledWith(
148+
'The "indexName" option of "restaurant" should be a non-empty string or an array of non-empty strings',
149+
)
150+
})
151+
152+
test('Test indexName with non-empty array containing empty string', async () => {
153+
validatePluginConfig({
154+
restaurant: {
155+
indexName: [''],
156+
},
157+
})
158+
expect(strapiMock.log.warn).toHaveBeenCalledTimes(0)
159+
expect(strapiMock.log.error).toHaveBeenCalledTimes(1)
160+
expect(strapiMock.log.error).toHaveBeenCalledWith(
161+
'The "indexName" option of "restaurant" should be a non-empty string or an array of non-empty strings',
162+
)
163+
})
164+
165+
test('Test indexName with non-empty array of strings', async () => {
166+
validatePluginConfig({
167+
restaurant: {
168+
indexName: ['validName1', 'validName2'],
133169
},
134170
})
135171
expect(strapiMock.log.warn).toHaveBeenCalledTimes(0)

0 commit comments

Comments
 (0)