глобальная сортировка по разным корзинам после агрегирования в elasticsearch - PullRequest
0 голосов
/ 12 июля 2020

образец в моем документе показан ниже. {"rackName": "rack005", "roomName": "roomB", "power": 132, "timestamp": 1594540106208}

я хочу получить последние данные по каждой стойке в предоставленную комнату, затем отсортируйте их по мощности. с помощью приведенного ниже кода я сделал что-то, чтобы приблизиться к своей цели. схожу с ума на последнем шаге, который выглядит как сортировка моих данных в разных сегментах по полю 'power'.

GET /power/_search
{
  "query": {
    "term": {
      "roomName.keyword": {
        "value": "roomB"
      }
    }
  }, 
  
  "aggs": {
    "rk_ag": {
      "terms": {
        "field": "rackName"
      },
      "aggs": {
        "latest": {
          "top_hits": {
            "sort": [
              {
                "timestamp": {
                  "order": "desc"
                }
              }
              ],
              "size": 1
          }
        }
      }
    }
    
  }
}

------ ----------------------------- результат -------------------- -----------------------------------

"aggregations" : {
    "rk_ag" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "rack003",
          "doc_count" : 4,
          "latest" : {
            "hits" : {
              "total" : {
                "value" : 4,
                "relation" : "eq"
              },
              "max_score" : null,
              "hits" : [
                {
                  "_index" : "power",
                  "_type" : "_doc",
                  "_id" : "0FXVQnMB8DPB7H9t6U0E",
                  "_score" : null,
                  "_source" : {
                    "rackName" : "rack003",
                    "roomName" : "roomB",
                    "power" : 115,
                    "timestamp" : 1594540117492
                  },
                  "sort" : [
                    1594540117492
                  ]
                }
              ]
            }
          }
        },
        {
          "key" : "rack004",
          "doc_count" : 4,
          "latest" : {
            "hits" : {
              "total" : {
                "value" : 4,
                "relation" : "eq"
              },
              "max_score" : null,
              "hits" : [
                {
                  "_index" : "power",
                  "_type" : "_doc",
                  "_id" : "1FXVQnMB8DPB7H9t6U0E",
                  "_score" : null,
                  "_source" : {
                    "rackName" : "rack004",
                    "roomName" : "roomB",
                    "power" : 108,
                    "timestamp" : 1594540117492
                  },
                  "sort" : [
                    1594540117492
                  ]
                }
              ]
            }
          }
        },
        {
          "key" : "rack005",
          "doc_count" : 4,
          "latest" : {
            "hits" : {
              "total" : {
                "value" : 4,
                "relation" : "eq"
              },
              "max_score" : null,
              "hits" : [
                {
                  "_index" : "power",
                  "_type" : "_doc",
                  "_id" : "2FXVQnMB8DPB7H9t6U0E",
                  "_score" : null,
                  "_source" : {
                    "rackName" : "rack005",
                    "roomName" : "roomB",
                    "power" : 118,
                    "timestamp" : 1594540114492
                  },
                  "sort" : [
                    1594540114492
                  ]
                }
              ]
            }
          }
        }
      ]
    }
  }

Ответы [ 2 ]

0 голосов
/ 12 июля 2020

Добавление к ответу @Jo. Как он упомянул, вы можете использовать несколько полей для сортировки.

Нижеприведенный запрос даст вам то, что вы ищете:

POST my_rack_index/_search
{
  "size": 0,
  "query": {
    "term": {
      "roomName.keyword": {
        "value": "roomB"
      }
    }
  },
  "aggs": {
    "rk_ag": {
      "terms": {
        "field": "rackName"
      },
      "aggs": {
        "latest": {
          "top_hits": {
            "sort": [                         <---- Note this part
              {
                "timestamp": {
                  "order": "desc"
                }
              },
              {
                "power": {
                  "order": "desc"
                }
              }
            ],
            "size": 1
          }
        }
      }
    }
  }
}

Итак, теперь, если для каждой стойки у вас есть два документа, то же имя стойки с точно такая же мощность , в ответе будет отображаться тот, у которого последняя временная метка .

Как будет работать сортировка то есть сначала он будет выполнять сортировку на основе метки времени, затем он будет выполнять сортировку на основе мощности, сохраняя сортировку на основе метки времени без изменений.

0 голосов
/ 12 июля 2020

Вы сортируете по timestamp вместо power. Попробуйте вместо этого:

GET /power/_search
{
  "query": {
    "term": {
      "roomName.keyword": {
        "value": "roomB"
      }
    }
  },
  "aggs": {
    "rk_ag": {
      "terms": {
        "field": "rackName"
      },
      "aggs": {
        "latest": {
          "top_hits": {
            "sort": [
              {
                "power": {
                  "order": "desc"
                }
              }
            ],
            "size": 1
          }
        }
      }
    }
  }
}

Вы можете сортировать по нескольким полям тоже.

...