Как получить текстовое поле текста в безболезненном скрипте в контексте фильтра поискового запроса elasti c? - PullRequest
1 голос
/ 23 апреля 2020

Я построил поисковый запрос elasti c с фильтром и в контексте фильтра, и я пишу безболезненный сценарий для фильтрации некоторых документов на основе тела текстового поля. Однако, когда я хочу получить доступ к текстовому полю, я получаю список терминов вместо исходного текста. Я ищу способ получить доступ к исходному тексту тела в безболезненном сценарии вместо списка терминов. В качестве альтернативы я хотел бы получить доступ к термину вектор частоты документа в этом контексте, если доступ к основной части текста невозможен.

Например, если я выполню этот запрос:

GET twitter/_search
{
  "query": {
      "bool": { 
      "must":{
        "term" : { "body" : "spark" }
      },
      "filter": [
        {
        "script" : {
                    "script" : {
                        "lang": "painless",
                        "source": """
                          String text = doc['body'].toString();
                          Debug.explain(text);
                         return true;
                      """

                    }
                }
      }
      ]
      } 

    }
}

Я получаю этот ответ:

  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 4,
    "skipped" : 0,
    "failed" : 1,
    "failures" : [
      {
        "shard" : 2,
        "index" : "twitter",
        "node" : "AClIunrSRUKb1gbhBz-JoQ",
        "reason" : {
          "type" : "script_exception",
          "reason" : "runtime error",
          "painless_class" : "java.lang.String",
          "to_string" : "[and, by, cutting, doug, hadoop, jack, jim, lucene, made, spark, the, was]",
          "java_class" : "java.lang.String",
          "script_stack" : [
            "Debug.explain(text);\n                         ",
            "              ^---- HERE"
          ],
          "script" : """
                          String text = doc['body'].toString();
                          Debug.explain(text);
                         return true;
                      """,
          "lang" : "painless",
          "caused_by" : {
            "type" : "painless_explain_error",
            "reason" : null
          }
        }
      }
    ]
  },
  "hits" : {
    "total" : 0,
    "max_score" : null,
    "hits" : [ ]
  }
}

Как видите, отладка показывает, что doc['body'].toString() на самом деле представляет собой список терминов [and, by, cutting, doug, hadoop, jack, jim, lucene, made, spark, the, was]. Я хотел бы получить доступ к исходному тексту, который в этом примере имеет вид "body" : "The Lucene was made by Doug Cutting and the hadoop was made by Jim and Spark was made by jack"

ПРИМЕЧАНИЕ. Я установил "fielddata": true и "store":true в этом поле, а также проиндексировал документ в виде body.exact поле, чтобы термины не анализировались, но, тем не менее, моя проблема в том, что я не могу получить доступ к исходному тексту скрипта в контексте фильтра и всегда получаю список уникальных терминов.

Большое спасибо за ваша помощь!

Ответы [ 2 ]

1 голос
/ 23 апреля 2020

Вы можете использовать keyword тип данных :

PUT twitter
{
  "mappings": {
    "_doc": {
      "properties": {
        "body": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword"
            }
          }
        }
      }
    }
  }
}
GET twitter/_search
{
  "query": {
    "bool": {
      "must": {
        "term": {
          "body": "spark"
        }
      },
      "filter": [
        {
          "script": {
            "script": {
              "lang": "painless",
              "source": """
                          String text = doc['body.keyword'].toString();
                          Debug.explain(text);
                         return true;
"""
            }
          }
        }
      ]
    }
  }
}

, уступающий

"painless_class" : "java.lang.String",
          "to_string" : "[The Lucene was made by Doug Cutting and the hadoop was made by Jim and Spark was made by jack]",
          "java_class" : "java.lang.String",
          "script_stack" : [
            "Debug.explain(text);\n                         ",
            "              ^---- HERE"
          ],
          "script" : """
                          String text = doc['body.keyword'].toString();
                          Debug.explain(text);
                         return true;
""",
0 голосов
/ 23 апреля 2020

Одним из решений, которое я нашел до сих пор, является использование нескольких полей и наличие подполя, например, body.raw, которое индексируется как keyword, и в этом случае, если мы вызовем doc['body.raw'].value.toString();, мы бы получить оригинальный текст. Мне все еще нравится находить решение, в котором мне не нужно индексировать два поля и получать исходный текст из _source или чего-то подобного.

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