J'essaie de trouver des tags associés à celui actuellement affiché. Chaque document de notre index est balisé. Chaque balise est formée de deux parties - un ID et un nom de texte:
{
...
meta: {
...
tags: [
{
id: 123,
name: 'Biscuits'
},
{
id: 456,
name: 'Cakes'
},
{
id: 789,
name: 'Breads'
}
]
}
}
Pour récupérer les balises associées, je recherche simplement les documents et j'obtiens un agrégat de leurs balises:
{
"query": {
"bool": {
"must": [
{
"match": {
"item.meta.tags.id": "123"
}
},
{
...
}
]
}
},
"aggs": {
"baked_goods": {
"terms": {
"field": "item.meta.tags.id",
"min_doc_count": 2
}
}
}
}
Cela fonctionne parfaitement, j'obtiens les résultats que je veux. Cependant, j'ai besoin à la fois du tag ID et nom pour faire quoi que ce soit d'utile. J'ai exploré comment y parvenir, les solutions semblent être:
Les options un et deux ne sont pas disponibles pour moi, donc je suis allé avec 3 mais il ne répond pas de la manière attendue. Étant donné la requête suivante (toujours à la recherche de documents également étiquetés avec "Biscuits"):
{
...
"aggs": {
"baked_goods": {
"terms": {
"field": "item.meta.tags.id",
"min_doc_count": 2
},
"aggs": {
"name": {
"terms": {
"field": "item.meta.tags.name"
}
}
}
}
}
}
J'obtiendrai ce résultat:
{
...
"aggregations": {
"baked_goods": {
"buckets": [
{
"key": "456",
"doc_count": 11,
"name": {
"buckets": [
{
"key": "Biscuits",
"doc_count": 11
},
{
"key": "Cakes",
"doc_count": 11
}
]
}
}
]
}
}
}
L'agrégation imbriquée comprend à la fois le terme de recherche et la balise que je recherche (renvoyée par ordre alphabétique).
J'ai essayé d'atténuer cela en ajoutant un exclude
à l'agrégation imbriquée, mais cela a trop ralenti la requête (environ 100 fois pour 500 000 documents). Jusqu'à présent, la solution la plus rapide consiste à déduper le résultat manuellement.
Quelle est la meilleure façon d'obtenir une agrégation de balises avec à la fois l'ID de balise et le nom de balise dans la réponse?
Merci d'être arrivé si loin!
De par son apparence, votre tags
n'est pas nested
. Pour que cette agrégation fonctionne, vous en avez besoin nested
pour qu'il y ait une association entre un id
et un name
. Sans nested
la liste des id
s est juste un tableau et la liste des name
s est un autre tableau:
"item": {
"properties": {
"meta": {
"properties": {
"tags": {
"type": "nested", <-- nested field
"include_in_parent": true, <-- to, also, keep the flat array-like structure
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
}
}
}
}
}
Notez également que j'ai ajouté au mappage cette ligne "include_in_parent": true
ce qui signifie que vos balises nested
se comporteront également comme une structure de type tableau "plat".
Ainsi, tout ce que vous aviez jusqu'à présent dans vos requêtes fonctionnera toujours sans aucune modification des requêtes.
Mais, pour votre requête particulière, l'agrégation doit changer en quelque chose comme ceci:
{
"aggs": {
"baked_goods": {
"nested": {
"path": "item.meta.tags"
},
"aggs": {
"name": {
"terms": {
"field": "item.meta.tags.id"
},
"aggs": {
"name": {
"terms": {
"field": "item.meta.tags.name"
}
}
}
}
}
}
}
}
Et le résultat est comme ceci:
"aggregations": {
"baked_goods": {
"doc_count": 9,
"name": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 123,
"doc_count": 3,
"name": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "biscuits",
"doc_count": 3
}
]
}
},
{
"key": 456,
"doc_count": 2,
"name": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "cakes",
"doc_count": 2
}
]
}
},
.....