Elasticsearch вложен больше, чем этот запрос

Можно ли выполнить запрос типа «Еще как этот» (https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-mlt-query.html) для текста внутри вложенного типа данных (https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html)?

Документ, который я хочу запросить (я не могу контролировать его форматирование, поскольку данные принадлежат другой стороне) выглядит примерно так:

{
  "communicationType": "Email",
  "timestamp": 1497633308917,
  "textFields": [
    {
      "field": "Subject",
      "text": "This is the subject of the email"
    },
    {
      "field": "To",
      "text": "[email protected]"
    },
    {
      "field": "Body",
      "text": "This is the body of the email"
    }
  ]
}

Я хочу выполнить запрос «Еще подобное» в теле письма. Раньше документы выглядели так:

{
  "communicationType": "Email",
  "timestamp": 1497633308917,
  "textFields": {
    "subject": "This is the subject of the email",
    "to: "[email protected]",
    "body": "This is the body of the email"
  }
}

И я смог выполнить запрос More Like This в теле письма следующим образом:

{
  "query": {
    "more_like_this": {
      "fields": ["textFields.body"],
      "like": "This is a similar body of an email",
      "min_term_freq": 1
    },
    "bool": {
      "filter": [
        { "term": { "communicationType": "Email" } },
        { "range": { "timestamp": { "gte": 1497633300000 } } }
      ]
    }
  }
}

Но теперь, когда источник данных устарел, мне нужно иметь возможность выполнять эквивалентный запрос к новому источнику данных, у которого тело электронной почты находится во вложенном типе данных. Я только хочу сравнить текст с полями «текст», у которых есть «заголовок» «Body».

Это возможно? И если да, то как бы выглядел запрос? И будет ли значительно снижена производительность при выполнении запроса для вложенного типа данных по сравнению с ранее выполненным запросом для невложенного документа? Даже после применения фильтров timestamp и communicationType останутся десятки миллионов документов, с которыми каждый запрос должен будет сравнивать аналогичный текст, поэтому производительность имеет значение.


person Joyce Liu    schedule 16.06.2017    source источник


Ответы (1)


На самом деле оказалось просто использовать запрос More Like This внутри вложенного запроса:

{
  "query": {
    "bool": {
      "must": {
        "nested": {
          "path": "textFields",
          "query": {
            "bool": {
              "must": {
                "more_like_this": {
                  "fields": ["textFields.text"],
                  "like_text": "This is a similar body of an email",
                  "min_term_freq": 1
                }
              },
              "filter": {
                "term": { "textFields.field": "Body" }
              }
            }
          }
        }
      },
      "filter": [
        {
          "term": {
            "communicationType": "Email"
          }
        },
        {
          "range": {
            "timestamp": {
              "gte": 1497633300000
            }
          }
        }
      ]
    }
  },
  "min_score": 2
}
person Joyce Liu    schedule 19.06.2017