Я довольно новичок в Elasticsearch и хочу выполнить следующее с помощью агрегации терминов:
- Получить список продуктов, соответствующих категории и выбранным спецификациям (функциям)
- Список спецификаций и возможных значений с указанием количества продуктов, которое вы получите, если выберете его
- Список спецификаций должен всегда содержать все спецификации всего набора данных, даже если он имеет счетчик 0, но только в пределах выбранной категории
- Продукты должны содержать хотя бы одно из выбранных значений выбранной спецификации
Это мое отображение:
{
"mapping": {
"product": {
"properties": {
"category": {
"type": "keyword"
},
"features": {
"properties": {
"breedte": {
"properties": {
"id": {
"type": "long"
},
"measure": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"value": {
"type": "float"
}
}
},
"diepte": {
"properties": {
"id": {
"type": "long"
},
"measure": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"value": {
"type": "float"
}
}
},
"hoogte": {
"properties": {
"id": {
"type": "long"
},
"measure": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"value": {
"type": "float"
}
}
}
}
},
"name": {
"type": "keyword"
},
"url": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
Это то, что у меня в данный момент («breedte» выбрано с 2 значениями, «hoogte» с 1)
GET _search
{
"from": 0,
"size": 15,
"sort":{
"name":"desc"
},
"stored_fields":[
"_id",
"name"
],
"query":{
"constant_score":{
"filter":{
"bool":{
"must":[
{
"term":{
"category":"Gaskookplaat"
}
},
{
"term":{
"features.hoogte.value":"55"
}
}
],
"should":[
{
"term":{
"features.breedte.value":"750"
}
},
{
"term":{
"features.breedte.value":"590"
}
}
]
}
}
}
},
"aggs":{
"categories":{
"filter":{
"bool":{
"should":[
]
}
},
"aggs":{
"breedte":{
"terms":{
"field":"features.breedte.value",
"min_doc_count":0
},
"meta":{
"id":"id",
"measure":"mm",
"title":"Breedte"
}
},
"hoogte":{
"terms":{
"field":"features.hoogte.value",
"min_doc_count":0
},
"meta":{
"value":"features.hoogte.value"
}
}
}
}
}
}
Результаты
{
"took": 10,
"timed_out": false,
"_shards": {
"total": 6,
"successful": 5,
"skipped": 0,
"failed": 1,
"failures": [
{
"shard": 0,
"index": ".kibana",
"node": "2fjW10M0RSa_imRTIMutww",
"reason": {
"type": "query_shard_exception",
"reason": "No mapping found for [name] in order to sort on",
"index_uuid": "x4687TCDRTalALulM9xLSg",
"index": ".kibana"
}
}
]
},
"hits": {
"total": 9,
"max_score": null,
"hits": [
{
"_index": "products",
"_type": "product",
"_id": "2014195",
"_score": null,
"sort": [
"5ZTAKGF87"
]
},
{
"_index": "products",
"_type": "product",
"_id": "2014049",
"_score": null,
"sort": [
"5RVSAKGF87"
]
},
{
"_index": "products",
"_type": "product",
"_id": "2023697",
"_score": null,
"sort": [
"9ZTAKG95"
]
},
{
"_index": "products",
"_type": "product",
"_id": "2009530",
"_score": null,
"sort": [
"RVSAKG959"
]
},
{
"_index": "products",
"_type": "product",
"_id": "2016478",
"_score": null,
"sort": [
"RVSAKG675"
]
},
{
"_index": "products",
"_type": "product",
"_id": "2015225",
"_score": null,
"sort": [
"5IXBBGW7"
]
},
{
"_index": "products",
"_type": "product",
"_id": "2010352",
"_score": null,
"sort": [
"75IXBGW"
]
},
{
"_index": "products",
"_type": "product",
"_id": "2018012",
"_score": null,
"sort": [
"0IXBBGW6"
]
},
{
"_index": "products",
"_type": "product",
"_id": "2009793",
"_score": null,
"sort": [
"60IXBGW"
]
}
]
},
"aggregations": {
"categories": {
"meta": {},
"doc_count": 9,
"hoogte": {
"meta": {
"value": "features.hoogte.value"
},
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 55,
"doc_count": 9
},
{
"key": 5,
"doc_count": 0
},
{
"key": 6,
"doc_count": 0
},
{
"key": 8,
"doc_count": 0
},
{
"key": 10,
"doc_count": 0
},
{
"key": 13,
"doc_count": 0
},
{
"key": 16,
"doc_count": 0
},
{
"key": 18,
"doc_count": 0
},
{
"key": 30,
"doc_count": 0
},
{
"key": 32,
"doc_count": 0
}
]
},
"breedte": {
"meta": {
"measure": "mm",
"id": "id",
"title": "Breedte"
},
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 750,
"doc_count": 5
},
{
"key": 590,
"doc_count": 4
},
{
"key": 70,
"doc_count": 0
},
{
"key": 83,
"doc_count": 0
},
{
"key": 85,
"doc_count": 0
},
{
"key": 94,
"doc_count": 0
},
{
"key": 98,
"doc_count": 0
},
{
"key": 110,
"doc_count": 0
},
{
"key": 120,
"doc_count": 0
},
{
"key": 165,
"doc_count": 0
}
]
}
}
}
}
Я думаю, что я на правильном пути, и результаты кажутся довольно хорошими, однако значения каждой спецификации - ИЛИ, а не И, в результате чего другие значения спецификации будут показывать 0 как число, если выбрано одно значение. То, что я хочу, это количество, которое я получу, когда добавлю это значение к выбору. Я надеюсь, что кто-то может указать мне правильное направление.