Как отсортировать объект по его дочерним объектным полям?

#elasticsearch

#elasticsearch

Вопрос:

Как я мог отсортировать продукты по, GroupModel.PeerOrder но только если GroupModel.ParentGroupId соответствует некоторому идентификатору?

Мои модели на C #:

 public class ProductModel
{
    public int Id { get; set; }
    public int Title { get; set; }
    public List<GroupModel> Groups { get; set; }
}

public class GroupModel
{
    public int Id { get; set; }
    public int Title { get; set; }
    public int ParentGroupId { get; set; }
    public int PeerOrder { get; set; }
}
  

Ответ №1:

Вот что у меня получилось (с помощью @ydrall — большое вам спасибо! :>):

Часть запроса (для нас отлично работает без этой первой части):

 "query": {
  "bool": {
        "must": [                
                {
                  "nested": {
                    "path": "groups", 
                    "query": {
                      "bool": {
                        "must": [ 
                          {
                            "match": {
                              "groups.parentGroupId": 3
                            }
                          }
                        ]
                      }
                    }
                  }
                }
    ]
  }
}
  

Сортировочная часть запроса:

 "sort": [
{
    "groups.peerOrder": { 
      "order": "asc",
        "nested_path": "groups",   
      "nested_filter": { 
        "match": {
          "groups.parentGroupId": 3 
        }
      }
    }
 }
  

Сопоставления индексов:

  "mappings": {
    "productmodel": {
      "properties": {
          "groups": {
          "type": "nested",
          "properties": {
            "id": {
              "type": "integer"
            },
            "parentGroupId": {
              "type": "integer"
            },
            "peerOrder": {
              "type": "integer"
            }
          }
        }
      }
    }
  }
  

Ответ №2:

Используйте вложенный запрос для фильтрации соответствия «GroupModel.Значения ParentGroupId«, а затем применить вложенный запрос сортировки для сортировки результатов по «GroupModel.PeerOrder«.

Согласно документации:

Вложенный запрос: Вложенный запрос позволяет запрашивать вложенные объекты / документы (см. вложенное сопоставление). Запрос выполняется к вложенным объектам / документам, как если бы они были проиндексированы как отдельные документы (так и есть, внутренне), и в результате получается корневой родительский документ (или родительское вложенное сопоставление). Вот пример сопоставления:

 PUT /my_index
{
    "mappings": {
        "_doc" : {
            "properties" : {
                "obj1" : {
                    "type" : "nested"
                }
            }
        }
    }
}

GET /_search
{
    "query": {
        "nested" : {
            "path" : "obj1",
            "score_mode" : "avg",
            "query" : {
                "bool" : {
                    "must" : [
                    { "match" : {"obj1.name" : "blue"} },
                    { "range" : {"obj1.count" : {"gt" : 5}} }
                    ]
                }
            }
        }
    }
}
  

Вложенный запрос сортировки: Можно выполнить сортировку по значению вложенного поля, даже если это значение существует в отдельном вложенном документе.

 GET /_search
{
  "query": {
    "nested": { 
      "path": "comments",
      "filter": {
        "range": {
          "comments.date": {
            "gte": "2014-10-01",
            "lt":  "2014-11-01"
          }
        }
      }
    }
  },
  "sort": {
    "comments.stars": { 
      "order": "asc",   
      "mode":  "min",   
      "nested_filter": { 
        "range": {
          "comments.date": {
            "gte": "2014-10-01",
            "lt":  "2014-11-01"
          }
        }
      }
    }
  }
}