我的项目有一个字符串字段(名称是urlOrContent),它可以很小(小于50个字符)或很长(超过50个字符),我只想每次返回前50个字符在特定的查询。我的数据库是弹性搜索,我的问题在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();
我找到了最好的答案。
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函数的调用,并且必须通过脚本返回所有返回的字段。
您可以将script_fields查询放在查询对象中,即在setQuery(查询)中。您的查询对象现在应该看起来像这样。
"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:on
script.engine.painless.inline.update:on
script.inline:on
script.indexed:on