Поиск по типу внутри массивов - PullRequest
0 голосов
/ 08 апреля 2019

Я пытаюсь реализовать запрос поиска по типу внутри массива. Это структура документов:

{
  "guid": "6f954d53-df57-47e3-ae9e-cb445bd566d3",
  "labels":
  [
    {
      "name": "London",
      "lang": "en"
    },
    {
      "name": "Llundain",
      "lang": "cy"
    },
    {
     "name": "Lunnainn",
     "lang": "gd"
    }
  ]
}

и до сих пор это то, с чем я пришел:

{
  "query": {
  "multi_match": {
  "fields": ["labels.name"],
  "query": name,
  "type": "phrase_prefix"
  }
}

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

То, что я пробовал, это:

{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "fields": ["labels.name"],
            "query": "london",
            "type": "phrase_prefix"
          }
        },
        {
          "term": {
            "labels.lang": "gd"
          }
        }
      ]
    }
  }
}

но эти запросы действуют на отдельные значения массива. Так, например, я хотел бы искать только валлийский язык (cy). Это означает, что мой запрос, который содержит название города, должен соответствовать только значениям, которые имеют «cy» в теге «lang». Как мне написать такой запрос?

Ответы [ 2 ]

0 голосов
/ 09 апреля 2019

Вы должны использовать Вложенный тип данных в отображении вместо Тип данных объекта .За подробным объяснением обращайтесь к этому:

https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html

Итак, вы должны определить отображение вашего поля примерно так:

 {
  "properties": {
    "labels": {
      "type": "nested",
      "properties": {
        "name": {
          "type": "text"
        },
        "lang": {
          "type": "keyword"
        }
      }
    }
  }
}

После этого вы можете запросить, используя Вложенный запрос как:

{
  "query": {
    "nested": {
      "path": "labels",
      "query": {
        "bool": {
          "must": [
            {
              "multi_match": {
                "fields": ["labels.name"],
                "query": "london",
                "type": "phrase_prefix"
              }
            },
            {
              "term": {
                "labels.lang": "gd"
              }
            }
          ]
        }
      }
    }
  }
}
0 голосов
/ 09 апреля 2019

Внутренне ElasticSearch выравнивает вложенные объекты JSON, поэтому он не может соотнести lang и name определенного элемента в массиве labels.Если вы хотите подобного рода корреляцию, вам нужно будет проиндексировать документы по-другому.

Обычный способ сделать это - использовать тип данных nested с соответствующим запросом nested.

В результате запрос будет выглядеть примерно так:

{
  "query": {
    "nested": {
      "path": "labels",
      "query": {
        "bool": {
          "must": [
            {
              "multi_match": {
                "fields": ["labels.name"],
                "query": "london",
                "type": "phrase_prefix"
              }
            },
            {
              "term": {
                "labels.lang": "gd"
              }
            }
          ]
        }
      }
    }
  }
}

Но учтите, что вам также необходимо указать вложенные отображения для ваших меток, например:

"properties": {
  "labels": {
    "type": "nested",
    "properties": {
      "name": {
        "type": "text"  
        /* you might want to add other mapping-related configuration here */
      },
      "lang": {
        "type": "keyword"
      }
    }
  }
}

Другие способы сделать это включают:

  • Индексирование каждой метки как отдельного документа, повторяя поле guid
  • Использование родительских / дочерних документов
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...