当前位置: 首页 > 知识库问答 >
问题:

如何在弹性搜索查询的过滤器上下文中以无痛脚本获取文本正文字段?

盖高畅
2023-03-14

我已经构建了一个带有过滤器的弹性搜索查询,并且在过滤器上下文中,我正在编写一个无痛苦的脚本来根据文本字段的主体过滤一些文档。然而,当我想访问文本字段时,我会得到一个术语列表,而不是原始文本。我正在寻找一种方法来访问无痛脚本中的原始文本正文,而不是术语列表。或者,如果无法访问文本正文,我希望在此上下文中访问文档的术语频率向量。

例如,如果我运行此查询:

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" : [ ]
  }
}

如你所见,调试显示了< code>doc['body']。toString()实际上是一个术语列表< code>[and,by,cutting,doug,hadoop,jack,jim,lucene,made,spark,the,was]。我想要的是访问原始文本,在本例中为< code >“body”:“Lucene由Doug Cutting制作,hadoop由Jim制作,Spark由jack制作”

注意:我已经在这个字段上设置了"field ddata": true"store": true,并且还在body.exact字段中对文档进行了索引,以便不会分析术语,但是我的问题是我无法在过滤器上下文中访问脚本中的原始文本,并且我总是得到唯一术语的列表。

非常感谢您的帮助!

共有2个答案

韦嘉颖
2023-03-14

到目前为止,我发现的一个解决方案是使用多字段并有一个子字段,例如body.raw,它被索引为关键字,在这种情况下,如果我们调用doc['body.raw'].value.toString();,我们将获得原始文本。我仍然喜欢找到一种解决方案,我不必索引两个字段并从_source或类似的东西中获取原始文本。

骆昊阳
2023-03-14

您可以使用关键字数据类型:

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;
""",
 类似资料:
  • 我是ES的新手,我正在尝试使用聚合编写搜索查询。 在写同样的东西时,我面临着无痛脚本的问题。 哪里可以得到完整的无痛脚本文档,用于弹性搜索?

  • 我有一个弹性查询脚本,用于使用我给出的参数计算地面距离,我必须在多个查询中使用它。是否有一种方法可以避免这种重复,例如,有一种计算全局变量并在所有脚本中使用它的方法。在本例中,我希望计算<code>距离 映射:

  • 我在elasticsearch中创建了一个观察器,当我们在索引中10分钟没有新条目或事件时,它会报告,这可以通过查看条目中的源字段来进一步划分。 我只得到了索引的最后10分钟,并查看了桶中不存在哪个源。 为此,我首先创建我们收到的所有源类型的列表,然后从返回的存储桶键创建一个列表。然后,我想比较列表以查看缺少哪个列表,然后将其传递到消息中。 我在for循环中遇到了一个通用错误。任何反馈对弹性和无痛

  • 我正在使用以下搜索: 我现在想使用弹性搜索在索引过程中提供的id ()来过滤结果。例如,{}。我猜你得用查询这个词。结果应该是只有当< code>_id匹配时,文档才返回。我该怎么做呢?

  • 我使用的是 ES 版本 7.0。我有一个商店索引,其中有空闲时间(开放和关闭时间)在UTC时间。我在 Integer 中存储了时间,以便它可以轻松地与无痛脚本中的当前时间匹配。 下面是一个示例文档: 下面是使用无痛脚本的查询: 上述查询适用于星期三的时间300,结果中给出了上述文档,但不适用于星期四的时间1400。看起来脚本总是匹配可用性数组中的第一个值。 我还试图循环浏览可用性日,但这并没有给我

  • 我有一份这样的文件 下面是我到目前为止所尝试的