Сортировка документов по вложенному полю

Я пытаюсь отсортировать результат, возвращаемый ElasticSearch, по вложенному полю sections.name следующим образом:

Отображение:

PUT /staff
{
    "mappings": {
        "list": {
            "properties": {
                "id": {"type": "text" },
                "name": {
                  "type":"text",
                  "fields" : {
                    "keyword" : {
                      "type" : "keyword",
                      "ignore_above" : 256
                    }
                  }
                },
                "sections" : {
                  "type":"nested",
                  "properties": {
                    "id": {"type":"text", "fielddata" : true},
                    "name": {
                    "fielddata" : true,
                    "type": "text",
                    "fields": {
                    "keyword" : {
                      "type" : "keyword",
                      "ignore_above" : 256
                      }
                    }
                  }
                }
              }
            }
        }
    }
}

документы:

POST /staff/list
{
    "id": 10,
    "name": "abc def",
    "sections":
    [
      {
        "id":"1",
        "name" : "zamphire"
      },{
        "id":"2",
        "name" : "warden"
      }
    ]
}

POST /staff/list
{
    "id": 9,
    "name": "abc def",
    "sections":
    [
      {
        "id":"1",
        "name" : "shaggi"
      },{
        "id":"2",
        "name" : "robert"
      }
    ]
}

POST /staff/list
{
    "id": 8,
    "name": "abc def",
    "sections":
    [
      {
        "id":"3",
        "name" : "zamphire"
      },{
        "id":"2",
        "name" : "abi"
      }
    ]
}

Я выполняю следующий запрос:

GET /staff/_search
{
  "from": 0,
  "query": {
    "nested": {
      "path": "sections",
      "query": {
        "match": {
          "sections.id": {
            "query": "1"
          }
        }
      }
    }
  },
  "size": 25,
  "sort": [
    {
      "sections.name": {
        "nested": {
          "filter": {
            "nested": {
              "path": "sections",
              "query": {
                 "term" : { "sections.id" : "1" }
              }
            }
          }
        },
        "order": "asc"
      }
    }
  ],
  "_source": {
    "includes": [
      "id",
      "name",
      "sections"
    ]
  }
}

Я получаю следующие результаты:

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : null,
    "hits" : [
      {
        "_index" : "staff",
        "_type" : "list",
        "_id" : "rJtyyGwBNB-cdBRb5XGR",
        "_score" : null,
        "_source" : {
          "name" : "abc def",
          "id" : 10,
          "sections" : [
            {
              "name" : "zamphire",
              "id" : "1"
            },
            {
              "name" : "warden",
              "id" : "2"
            }
          ]
        },
        "sort" : [
          null
        ]
      },
      {
        "_index" : "staff",
        "_type" : "list",
        "_id" : "rZtyyGwBNB-cdBRb6nHU",
        "_score" : null,
        "_source" : {
          "name" : "abc def",
          "id" : 9,
          "sections" : [
            {
              "name" : "shaggi",
              "id" : "1"
            },
            {
              "name" : "robert",
              "id" : "2"
            }
          ]
        },
        "sort" : [
          null
        ]
      }
    ]
  }
}

Я ожидаю, что раздел shaggi будет перед zamphire, и поэтому порядок двух документов должен быть обратным.

Я заметил это в результатах:

"sort" : [
  null
]

Это связано? Что мне здесь не хватает?


person Nour    schedule 25.08.2019    source источник


Ответы (1)


Изменение части sort на это должно выполнять работу в соответствии с документы

  "sort": [
    {
      "sections.name": {
        "order": "asc", 
        "nested": {
          "path": "sections",
          "filter": {
            "term" : { "sections.id" : "1" }
          }
        }
      }
    }
  ]

Возвращает

{
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [
      {
        "_index" : "staff",
        "_type" : "_doc",
        "_id" : "8hSJyWwBHfpsFyAs9f_8",
        "_score" : null,
        "_source" : {
          "name" : "abc def",
          "id" : 9,
          "sections" : [
            {
              "name" : "shaggi",
              "id" : "1"
            },
            {
              "name" : "robert",
              "id" : "2"
            }
          ]
        },
        "sort" : [
          "shaggi"
        ]
      },
      {
        "_index" : "staff",
        "_type" : "_doc",
        "_id" : "8RSJyWwBHfpsFyAs5v98",
        "_score" : null,
        "_source" : {
          "name" : "abc def",
          "id" : 10,
          "sections" : [
            {
              "name" : "zamphire",
              "id" : "1"
            },
            {
              "name" : "warden",
              "id" : "2"
            }
          ]
        },
        "sort" : [
          "zamphire"
        ]
      }
    ]
  }
}

Протестировано с помощью elasticsearch 7.2.0.

Надеюсь, это поможет.

person Rob    schedule 25.08.2019
comment
ДА ДА ДА ДА ! работал как шарм. Я не могу поверить, насколько глупой была ошибка и как легко было ее исправить! Я использую клиент NEST .Net и думаю, что каким-то образом использовал неправильную комбинацию свободного API. Большое спасибо, вы спасли мой день. - person Nour; 25.08.2019
comment
Не могли бы вы поделиться запросом NEST Fluent, который вы пробовали в задачах github.com/elastic/elasticsearch-net? Может быть, это можно улучшить, чтобы другие люди не попадали в такие же проблемы. Спасибо. - person Rob; 25.08.2019
comment
Хорошая идея. Однако я использовал поддельный пример в своем вопросе, аналогичном моей проблеме, чтобы изолировать все остальные факторы. Так что убрать ненужный код будет непросто, но я посмотрю, что смогу сделать. спасибо за предложение, хотя. - person Nour; 25.08.2019