我有一个在ES中建立索引的文档。该文档具有3个文本字段F1
,F2
和F3
。
当我尝试使用Java API搜索该文档时,我只有字段F1
和F2
的值,而字段F3
却显示为空。
QueryBuilder query = //Some query
SearchResponse response = client.prepareSearch(index)
.addDocValueField("F1.keyword")
.addDocValueField("F2.keyword")
.addDocValueField("F3.keyword")
.setQuery(query)
.execute()
.actionGet();
SearchHit hit = response.getHits().getAt(0);
System.out.println("F1 : "+hit.getField("F1.keyword").getValue());
System.out.println("F2 : "+hit.getField("F2.keyword").getValue());
System.out.println("F3 : "+hit.getField("F3.keyword").getValue()); // empty
我的字段F3
可能很长。在我用于测试的文档中,它的字符数大于300,并且可能更长。
我的索引映射是:
"mappings": {
"MyIndex": {
"properties": {
"F1": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"F2": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"F3": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
所以我将ignore_above
的映射中的F3
字段更新为20000(可能是个坏主意?),但是我仍然有相同的行为。
问题是什么,正确的方法是什么?
注意:
F3
上进行任何分析/术语搜索,只需在查询匹配F1
或F2
时检索其值。编辑:
奇怪的是,当我用带有查询的浏览器请求elasticsearch时,我得到了预期的结果:
http://localhost:9200/MyIndex/_search?pretty=true?{"query": {"match_all": {}}}
答案 0 :(得分:1)
在Elasticsearch中,默认行为将文本字符串映射为两种不同的Elasticsearch类型:text
和keyword
。它们是不同的东西,用于不同的目的,主要是text
是全文搜索字段,而keyword
就像结构化常量值。在the docs
对于您而言,默认包含keyword
字段似乎没有帮助。在查询中,您只需获取“常规” F3
字段和/或F1
和F2
的常规字段即可。
最后,我对ES Java客户端不是很熟悉,但是如果您想进行源过滤(即,仅从请求中获取值的子集),那么我不认为addDocValueField()
是对。检出:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/5.6/java-rest-high-search.html#_source_filtering