我正在一个有字符串字段(名称为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();
答案 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函数的调用,并且必须通过脚本返回所有返回的字段。