Isolez et recherchez des données par locataire ou par base de connaissances sans maintenir un index distinct pour chacun. Cet exemple utilise une Collection (un ensemble de données avec une définition de champ unifiée) pour gérer deux locataires. Les locataires correspondent à deux Slices (partitions de données métier), tenant-a et tenant-b. Vous spécifiez le locataire via _slice lors de l'écriture et de l'interrogation des données. Dans cet exemple, les noms des Slice sont des ID de locataire. Vous pouvez également nommer un Slice selon un autre identifiant métier, tel qu'une base de connaissances. La sélection d'une étendue de données par identifiant métier est appelée mode namespace (exact), qui est le mode par défaut ; l'étape 3 décrit quand utiliser d'autres étendues de requête.
Les applications accèdent aux données via le nom de la Collection et le nom du Slice métier. Un Slice limite l'étendue des données ; il ne constitue pas une limite de permission de compte. Votre application doit toujours vérifier les identités des locataires et autoriser l'accès. @/id="p-qs-pre2"
Pour effectuer votre première recherche, il vous suffit de créer une Collection → écrire des données → interroger les données. Les sections suivantes indiquent trois tâches comme facultatives : pré-créer des Backings (les index sous-jacents qui stockent vos documents), enregistrer des Slices à l'avance et réchauffer le cache. Avant d'intégrer des locataires par lots, pré-créez des Backings et enregistrez des Slices. Si la latence de la première requête est importante pour vous, réchauffez d'abord le cache. @/id="p-qs-intro2"
Préparer une instance
Vous avez besoin d'une instance de moteur Agent disponible. Si vous n'en avez pas encore créé, commencez par Créer une instance de moteur Agent. Exécutez les requêtes de cette rubrique dans Kibana Dev Tools. Le compte que vous utilisez doit disposer des permissions de gestion de Collection et de lecture/écriture des données. Pour plus d'informations, consultez Permissions de Collection.
Étape 1 : Créer une collection
Créez la Collection knowledge-chunks pour définir des champs tels que l'identifiant du locataire, le titre, le corps et le vecteur en un seul endroit. Vous pouvez utiliser les vecteurs d'exemple tels quels pour un essai. Lorsque vous connectez une charge de travail réelle, assurez-vous que les dimensions du vecteur et la métrique de similarité correspondent à votre modèle.
PUT /_slice_collection/knowledge-chunks
{
"max_slices_per_shard": 200,
"settings": {
"index.number_of_shards": 2,
"index.number_of_replicas": 2
},
"mappings": {
"properties": {
"tenant_id": { "type": "keyword" },
"document_id": { "type": "keyword" },
"title": { "type": "text" },
"content": { "type": "text" },
"category": { "type": "keyword" },
"updated_at": { "type": "date" },
"embedding": {
"type": "dense_vector",
"dims": 4,
"index": true,
"similarity": "cosine",
"index_options": {
"type": "bbq_disk"
}
}
}
}
}
Vérifiez que la réponse renvoie acknowledged: true @/id="qs-ack0" , ce qui indique que la configuration de la Collection est créée. @/id="p-qs-s1-2"
Le système stocke les documents dans des Backings (index sous-jacents), et un Backing peut contenir plusieurs Slices. max_slices_per_shard @/id="qs-msps0" contrôle le nombre de nouveaux Slices que chaque Backing accepte. Une valeur plus petite fait en sorte que les nouveaux Slices commencent à utiliser d'autres Backings plus tôt. Ce paramètre ne limite pas le nombre de documents dans un seul Slice. Pour les calculs de capacité, consultez Comment les paramètres de capacité prennent effet. @/id="p-qs-s1-3"
Pré-créer des Backings (facultatif, recommandé)
Vous pouvez ignorer cette étape pour un premier essai car le système crée des Backings à la demande. Avant d'intégrer des locataires par lots ou d'importer des données, préparez 5 Backings. La pré-création de Backings réduit l'attente pour la création d'index lors de la première écriture et répartit les données des nouveaux locataires sur plusieurs index sous-jacents, ce qui aide à distribuer les charges de lecture et d'écriture :
PUT /_slice_collection/knowledge-chunks/backings?count=5
Vérifiez que la réponse renvoie acknowledged: true @/id="qs-ack1" et que backings @/id="qs-backings0" liste 5 noms. L'exécution répétée de la requête vérifie et complète le même ensemble d'index ; les données existantes ne sont pas redistribuées par conséquent. Dans un environnement de production, ajustez le count en fonction de votre volume de données et des ressources de shard. Pour les paramètres et les règles d'allocation, consultez Pré-créer des Backings. @/id="p-qs-bk2"
Enregistrer des slices à l'avance (facultatif)
Par défaut, un Slice est enregistré automatiquement lors de la première écriture. L'enregistrement préalable des partitions métier lors de l'intégration des locataires supprime l'attente d'enregistrement de la première écriture métier :
PUT /_slice_collection/knowledge-chunks/slices
{
"slices": ["tenant-a", "tenant-b"]
}
Vérifiez que le niveau supérieur errors @/id="qs-errors0" est false @/id="qs-false0" et que chaque items[].result @/id="qs-items0" est created @/id="qs-created0" ou noop @/id="qs-noop0" . created @/id="qs-created1" signifie un nouvel enregistrement, et noop @/id="qs-noop1" signifie que le Slice existe déjà et ne nécessite aucune modification. Si un élément est failed @/id="qs-failed0" , résolvez son erreur avant d'écrire des données. @/id="p-qs-rs2"
Étape 2 : Écrire des données
Ne transmettez pasrefreshpour les écritures régulières, et n'appelez pas_refreshdans le code de l'application. Ces opérations peuvent augmenter considérablement la surcharge de la publication des données, des lectures du stockage objet et des actualisations des nœuds de requête. Utilisez refresh=wait_for uniquement à un point de synchronisation peu fréquent, et examinez d'abord Conditions applicables et coûts.
Écriture en bloc
Utilisez une seule requête Bulk pour écrire deux documents pour chaque locataire. Les deux locataires utilisent les mêmes valeurs _id mais un contenu de document différent. Cela vérifie que _iddoit seulement être unique au sein du même Slice. Les documents qui partagent un ID entre différents Slices ne s'écrasent pas mutuellement.
POST /_bulk
{ "index": { "_index": "knowledge-chunks", "_id": "chunk-1001", "_slice": "tenant-a" } }
{ "tenant_id": "tenant-a", "document_id": "doc-refund-policy", "title": "Refund and return policy", "content": "You can request a refund for a duplicate purchase within seven days after the order is completed.", "category": "after-sales", "updated_at": "2026-07-30T10:00:00Z", "embedding": [0.82, 0.10, 0.05, 0.03] }
{ "index": { "_index": "knowledge-chunks", "_id": "chunk-1001", "_slice": "tenant-b" } }
{ "tenant_id": "tenant-b", "document_id": "doc-shipping-status", "title": "Track shipping status", "content": "Open the shipping information on the order details page to view the latest delivery status.", "category": "shipping", "updated_at": "2026-07-30T10:01:00Z", "embedding": [0.12, 0.78, 0.06, 0.04] }
{ "index": { "_index": "knowledge-chunks", "_id": "chunk-1002", "_slice": "tenant-a" } }
{ "tenant_id": "tenant-a", "document_id": "doc-change-address", "title": "Change the shipping address", "content": "Before the order is shipped, you can change the shipping address on the order details page.", "category": "orders", "updated_at": "2026-07-30T10:02:00Z", "embedding": [0.75, 0.16, 0.06, 0.03] }
{ "index": { "_index": "knowledge-chunks", "_id": "chunk-1002", "_slice": "tenant-b" } }
{ "tenant_id": "tenant-b", "document_id": "doc-invoice", "title": "Request electronic invoicing", "content": "After the order is completed, you can request electronic invoicing on the invoice management page.", "category": "billing", "updated_at": "2026-07-30T10:03:00Z", "embedding": [0.18, 0.70, 0.08, 0.04] }
Bulk utilise le format NDJSON. Chaque opération et chaque document occupe une ligne, et le corps de la requête doit se terminer par un caractère de nouvelle ligne. Dans une requête Bulk, _slice fait partie des métadonnées d'action ; dans les requêtes de document unique et de requête, il s'agit d'un paramètre de requête URL. Vérifiez que le niveau supérieur errors @/id="qs-errors1" dans la réponse est false @/id="qs-false1" . Si certaines opérations échouent, inspectez les erreurs dans items @/id="qs-items1" une par une et résolvez-les avant de continuer. @/id="p-qs-bulk2"
La valeur _index @/id="qs-idx0" dans une réponse d'écriture peut être un nom d'index sous-jacent correspondant à .sc-* @/id="qs-sc0" . La valeur _routing @/id="qs-routing0" dans une réponse de lecture ou de requête peut être un identifiant interne de Slice généré par le système (slice_uid @/id="qs-suid0" ) qui diffère du nom de Slice métier que vous avez transmis. Ceci est attendu. Continuez à utiliser les noms métier tels que knowledge-chunks @/id="qs-kc1" et tenant-a @/id="qs-ta1" dans les requêtes suivantes. Ne traitez pas ces valeurs internes comme le nom de la Collection ou le paramètre _slice @/id="qs-slice1" , et n'analysez pas leur format. @/id="p-qs-bulk3"
Vérifier les écritures par ID (facultatif)
GET lit les données en temps réel par défaut, donc vous n'avez normalement pas besoin d'attendre une actualisation de recherche. Lisez chunk-1001 depuis chaque locataire :
GET /knowledge-chunks/_doc/chunk-1001?_slice=tenant-a
GET /knowledge-chunks/_doc/chunk-1001?_slice=tenant-b
Le champ found @/id="qs-found0" devrait être true @/id="qs-true0" dans les deux réponses, et les titres devraient être « Refund and return policy » et « Track shipping status ». Cela confirme que les documents ayant le même ID sont stockés séparément dans les deux Slices. Pour le comportement de lecture lorsque le shard principal n'est pas disponible, consultez Vérifier une écriture par ID. @/id="p-qs-v2"
Étape 3 : Interroger les données au sein d'un locataire
Une fois l'écriture réussie, attendez environ 5 secondes pour que l'actualisation automatique en arrière-plan rende les données consultables, puis exécutez le réchauffement ou la requête. Si les résultats n'incluent pas encore les nouvelles données, utilisez la requête GET en temps réel dans Vérifier les écritures par ID (Étape 2) pour confirmer que le document existe. Attendez ensuite un cycle d'actualisation automatique supplémentaire et réessayez. Le temps réel jusqu'à ce que les données deviennent consultables dépend également de la charge ; 5 secondes ne constituent pas un délai d'achèvement.
Réchauffer le Slice à interroger (facultatif, recommandé)
Un réchauffement réduit l'attente pour le chargement des données froides depuis le stockage objet lors de la première requête. La prochaine requête cible tenant-a, vous pouvez donc d'abord charger ses données consultables dans le cache du nœud de requête pour que les requêtes suivantes les réutilisent. Cet exemple attend de manière synchrone afin que le résultat soit facile à observer :
POST /knowledge-chunks/_warm_slice?_slice=tenant-a&wait_for_completion=true&timeout=60s
Vérifiez que la requête réussit et que _shards.failed @/id="qs-sf0" est 0 @/id="qs-0a" . Cet exemple a déjà écrit des données, donc _shards.total=0 @/id="qs-st0" est inattendu. Si vous voyez cette valeur, confirmez d'abord que les shards de requête sont disponibles, utilisez une requête réelle pour confirmer que les données sont consultables, puis réessayez le réchauffement si nécessaire. En cas de délai d'expiration ou d'échec de shard, inspectez l'erreur avant de réessayer. Un réchauffement couvre uniquement les données déjà consultables à ce moment-là et n'inclut pas les données ajoutées ultérieurement. @/id="p-qs-w2"
Dans un environnement de production, réchauffez les données de manière asynchrone à l'avance aux points d'accès prévisibles, par exemple lorsqu'un utilisateur sélectionne une base de connaissances, et contrôlez la concurrence. Les requêtes suivantes réutilisent alors le cache, vous n'avez donc pas besoin d'attendre un réchauffement à chaque requête. Une réponse ACCEPTED @/id="qs-acc0" asynchrone signifie seulement que la requête est soumise. Pour savoir comment déterminer le résultat, consultez Déterminer le résultat d'un réchauffement asynchrone. @/id="p-qs-w3"
Exécuter une recherche vectorielle
Interrogez uniquement les documents dans tenant-a et renvoyez les champs utilisés pour l'affichage métier et la vérification de l'étendue :
POST /knowledge-chunks/_search?_slice=tenant-a
{
"knn": {
"field": "embedding",
"query_vector": [0.80, 0.12, 0.05, 0.03],
"k": 10,
"num_candidates": 100
},
"_source": ["tenant_id", "document_id", "title", "content"]
}
Vérifiez que timed_out @/id="qs-to0" est false @/id="qs-false2" et que _shards.failed @/id="qs-sf1" est 0 @/id="qs-0b" . Les résultats doivent inclure « Refund and return policy » et « Change the shipping address », et le tenant_id @/id="qs-tid0" de chaque résultat doit être tenant-a @/id="qs-ta4" . Après avoir changé _slice @/id="qs-slice2" dans l'URL en tenant-b @/id="qs-tb1" , les résultats doivent être « Track shipping status » et « Request electronic invoicing ». Les deux locataires utilisent les mêmes ID de document, vérifiez donc l'étendue par le champ locataire et le titre au lieu de comparer uniquement les ID. @/id="p-qs-se2"
tenant_id @/id="qs-tid1" est un champ régulier utilisé pour l'affichage et la vérification ; l'étendue réelle de la requête est déterminée par _slice @/id="qs-slice3" . Le mode namespace nécessite une étendue explicite par défaut, et l'omission de _slice @/id="qs-slice4" renvoie une erreur. N'utilisez pas _slice=_all @/id="qs-sliceall0" pour les requêtes métier régulières. Pour les conditions applicables des requêtes multi-Slice et de données complètes, consultez Spécifier l'étendue de la requête. Une recherche régulière n'a pas besoin de récupérer les valeurs vectorielles ; le serveur effectue le calcul KNN. @/id="p-qs-se3"
Étapes suivantes
Intégration de locataires par lots, capacité et gestion du cycle de vie : Gestion de Collection. @/id="p-qs-nx1"
Écritures de document unique, lectures en bloc et développement de requêtes : Lire et écrire des données. @/id="p-qs-nx2"
Qualité de la recherche vectorielle : Ajuster les résultats de la recherche vectorielle. @/id="p-qs-nx3"
Avant la mise en production, examinez Limites et configurez la surveillance et les permissions comme décrit dans Permissions de Collection. @/id="p-qs-nx4"
Sélection de cluster après achèvement du clustering hors ligne : Sélectionner automatiquement les clusters candidats. @/id="p-qs-nx5"