返回Elasticsearch Java API中已分析的未存储文本字段的子字符串

时间:2019-03-16 11:29:45

标签: java elasticsearch

我正在一个有字符串字段(名称为urlOrContent)的项目中工作,它可以很小(少于50个字符)或很长(超过50个字符),我只想返回前50个字符每次基于特定查询。我的数据库是elasticsearch,问题在this link中提出,发问者的回答似乎正确(已分析urlOrContent字段,未存储文本字段)。它使用以下脚本:

{
   "script_fields": {
      "substring": {
         "script": {
            "lang": "painless",
            "inline": "params._source.text.substring(0, 100)"
         }
      }
   }
}

但是我的主要问题是我找不到与elasticsearch java api代码等效的代码。实际上,应该在下面的代码中添加什么,该代码仅返回urlOrContent字段的前50个字符?请注意,在某些情况下,该字段甚至可能不包含50个字符,然后应返回整个字符串。

String queryString =
    EnumLinkFields.CREATE_TIME.getFieldName() + ":(>=" + dateFrom + " AND <=" + dateTo + ")";

QueryBuilder query = QueryBuilders.queryStringQuery(queryString);

SearchResponse response = TRANSPORT_CLIENT.prepareSearch(MY_INDEX)
                .setTypes(MY_TYPE)
                .setSearchType(SEARCH_TYPE)
                .setQuery(query)
                .setFetchSource(null, new String[]{EnumLinkFields.USER_ID.getFieldName()})
                .setFrom(offset)
                .setSize(count)
                .addSort(orderByField, sortOrder)
                .execute().actionGet();

2 个答案:

答案 0 :(得分:0)

您可以将您的script_fields查询放入查询对象,即 setQuery(query)中。 您的查询对象现在应该看起来像这样。

    "query" : {
        "term" : { "user" : "kimchy" }
    }

在对象中添加script_fields后,它应该变为:

"query" : {
  "term" : { "user" : "kimchy" }
},
"script_fields": {
  "urlOrContent": {
     "script": {
        "lang": "painless",
        "inline": "if(params._source.urlOrContent.length() > 50){
                    params._source.urlOrContent.substring(0, 50)
                   }
                   else {
                   params._source.urlOrContent
                   }"  
   }
  }
}

产生的匹配将具有包含所需子字符串的字段数组。

您必须通过像这样更改elasticsearch.yml文件来启用脚本,然后重新启动elasticsearch: script.engine.painless.inline.aggs:打开

script.engine.painless.inline.update:开

script.inline:

脚本索引:在

答案 1 :(得分:0)

我找到了最佳答案。

String queryString =
    EnumLinkFields.CREATE_TIME.getFieldName() + ":(>=" + dateFrom + " AND <=" + dateTo + ")";

QueryBuilder query = QueryBuilders.queryStringQuery(queryString);

String codeUrlOrContent = "if (" + EnumElasticScriptField.URL_OR_CONTENT.getFieldName() + ".length() > 50) {" +
        "return " + EnumElasticScriptField.URL_OR_CONTENT.getFieldName() + ".substring(0, 50);" +
        "} else { " +
        "return " + EnumElasticScriptField.URL_OR_CONTENT.getFieldName() + "; }";

Script scriptUrlOrContent = new Script(ScriptType.INLINE, "painless",
        codeUrlOrContent, Collections.emptyMap());

Script scriptIsUrl = new Script(ScriptType.INLINE, "painless",
        EnumElasticScriptField.IS_URL.getFieldName(), Collections.emptyMap());

SearchResponse response = TRANSPORT_CLIENT.prepareSearch(MY_INDEX)
                .setTypes(MY_TYPE)
                .setSearchType(SEARCH_TYPE)
                .setQuery(query)
                .addScriptField(EnumLinkFields.URL_OR_CONTENT.getFieldName(), 
                     scriptUrlOrContent)
                .addScriptField(EnumLinkFields.IS_URL.getFieldName(), scriptIsUrl)
                .setFrom(offset)
                .setSize(count)
                .addSort(orderByField, sortOrder)
                .execute().actionGet();

请注意,必须删除对setFetchSource函数的调用,并且必须通过脚本返回所有返回的字段。