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

以字符串形式检查整个弹性搜索文档中的特定文本

微生德泽
2023-03-14

我正在研究一个用例,其中我想确定弹性搜索中的哪个文档在任何字段值(索引和非索引)中都有特定的关键字。在SQL的情况下,这将是直截了当的,尽管它会有点重。就像Postgres一样,我们可以做到:

select count(1) from table where data::text like '%keyword%'

但是,在弹性搜索的情况下,我正在试验无痛脚本。以下是我的尝试:

  • 使用脚本筛选器
  • 添加无痛脚本以将整个文档 JSON 转换为字符串
  • 并且,在脚本中,如果文档字符串包含关键字,则返回 true

现在,我在scripted_field子句中尝试了以下各项的不同变体,以将整个文档转换为字符串:

 - doc.toString()
 - doc['_source'].value
 - params._source.toString()
 - ctx._source.value.toString()

而且,没有一个奏效。

然而,我可以看到检索单个字段值是可行的。因此,下面的查询给出了下面提到的结果:

"script_fields": {
    "myfield": {
      "script": """
            return params._source.id.toString();
      """
    }
}

结果:

{
  "_index": "myindex",
  "_type": "mytype",
  "_id": "1557e321-b6be-491f-a869-9309194af658",
  "_score": 13.808922,
  "myfield": {
    "text": [
      "1557e321-b6be-491f-a869-9309194af658"
    ]
  }
}

任何人都可以在ES中帮助在运行时将整个文档json转换为字符串吗?

共有1个答案

罗安宁
2023-03-14

经过大量实验,并参考了一些博客,我找到了一种解决方法,包括迭代文档的每个字段并递归地构建文档字符串。

这是最终的工作版本:

{
  "query": {
    "bool": {
      "must": [
        <some clause here>
      ],
      "filter": {
        "script": {
          "script": """
              void processFields(StringBuilder sb, def x) {
               if( x != null) {
                 if (x instanceof List) {
                   for (def v: x) {
                     processFields(sb, v);
                   }
                 }
                 
                 if ((x instanceof HashMap)) {
                   HashMap map = (HashMap) x;
                   for (def v: map.values()) {
                     processFields(sb, v);
                   }
                 }
                 sb.append(x);
                 sb.append('~|~');
               }
             }
            
            StringBuilder sb = new StringBuilder();
            for (key in params._source.keySet()) {
              processFields(sb, params._source.get(key));
            }
            String s = sb.toString();
            return s.contains('<keyword-to-search-in-entire-document-string>');
"""
        }
      }
    }
  }
}

注意:确保<code>processFields()</code>中使用的分隔符与您要搜索的分隔符不同:

Ref用于递归迭代所有文档字段:https://alexmarquardt.com/category/painless/

 类似资料:
  • 问题内容: JS中是否有办法以字符串形式获取 html 标记内的整个HTML ? 问题答案: MS 不久前添加了和属性。 根据MDN的说明,Firefox 11,Chrome 0.2,InternetExplorer 4.0,Opera 7,Safari 1.3,Android,Firefox Mobile 11,IE Mobile,Opera Mobile和SafariMobile支持。在DOM

  • 我刚开始做弹性搜索。我想通过子字符串搜索,它由数字和像“/”和“-”这样的符号组成。例如,我使用默认设置和一个索引字段创建索引: 然后,我将一些数据添加到我的索引中: 不返回命中。如果我移除星形符号,那么作为回应,我会看到两个点击:“1/1-35”和“1/2-25”。如果我尝试用反斜杠(“1\/1*”)转义斜杠符号,结果分别是相同的。 当我的查询中有“-”符号时,那么我必须转义这个Lucene特殊

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

  • 实现此功能的推荐方法是什么?注意,我使用的是查询字符串查询。

  • 我是ES的新手,我正在尝试使用聚合编写搜索查询。 在写同样的东西时,我面临着无痛脚本的问题。 哪里可以得到完整的无痛脚本文档,用于弹性搜索?

  • 尝试排除其中一个子文档与查询不匹配的顶级文档。 对于下面的示例,我试图排除其中一个嵌套作业具有并且与匹配的所有文档。但是,由于其中一个嵌套作业文档与和公司匹配,因此返回此文档。我使用的是一个嵌套查询,其中公司名称必须匹配,并且过滤器的当前值为false。我如何才能使以下文件不被退回?