我正在尝试在Java API中使用ElasticSearch。作为JSON文件(名为Google.json),我使用以下结构:
{
"markers": [
{
"point":"new GLatLng(40.266044,-74.718479)",
"homeTeam":"Lawrence Library",
"awayTeam":"LUGip",
"markerImage":"images/red.png",
"information": "Linux users group meets second Wednesday of",
"fixture":"Wednesday 7pm",
"capacity":"",
},
{
"point":"new GLatLng(40.266044,-74.75022)",
"homeTeam":"Hamilton Library",
"awayTeam":"LUGip HW SIG",
"markerImage":"images/white.png",
"information": "Linux users group meets second Tuesday.",
"fixture":"Tuesday 7pm",
"capacity":"",
}
]
}
使用Jackson我将此文件转换为Java Hashmap。然后我尝试在现场搜索"灯具"为了这个词"星期二"。我找到了这个,但结果我得到了完整的标记"列回而不是仅列出第二个元素。我现在想知道我的方法存在什么问题。
这是我的Java代码:
JSONParser parser= new JSONParser();
String path="d:\\Google.json";
Node node = nodeBuilder().local(true).node();
Client client = node.client();
/* Jackson mapper*/
ObjectMapper mapper = new ObjectMapper();
File jsonFile=new File(path);
try {
/*Read in file using Jackson into HashMap*/
Map<String, Object> mapObject=new HashMap<String, Object>();
mapObject = mapper.readValue(jsonFile, new TypeReference<Map<String, Object>>(){});
/*Create index*/
IndexResponse response=null;
response = client.prepareIndex(index, type)
.setSource(mapObject)
.execute()
.actionGet();
} catch (JsonParseException e1) {
e1.printStackTrace();
} catch (JsonMappingException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
QueryBuilder qb=QueryBuilders.matchQuery("fixture","Tuesday");
SearchResponse response= client.prepareSearch(index)
.setTypes(type)
.setSearchType(SearchType.QUERY_AND_FETCH)
.setQuery(qb)
.setFrom(0)
.setSize(100)
.setExplain(true)
.execute().actionGet();
SearchHit[] results = response.getHits().getHits();
System.out.println("Current results: " + results.length);
for (SearchHit hit : results) {
System.out.println("------------------------------");
Map<String,Object> result = hit.getSource();
System.out.println(result);
}
对此有任何提示/帮助会很棒!
答案 0 :(得分:1)
看起来杰克逊把所有东西都放到了一个JSON对象中。然后将其编入索引为elasticsearch中的单个文档。
运行查询时,Elasticsearch始终返回完整文档作为结果。无法返回部分文档。因此,在运行查询时,将返回包含具有名为“Tuesday”的fixture的元素的所有文档。由于您的单个文档包含星期三和星期二作为固定装置,因此即使您仅搜索星期二,这两个元素也会返回。整个文档都返回了,即使只有匹配“星期二”的部分实际上与查询匹配。
以下章节必读:Modelling your data基本上,有两种解决方法:
1)将您的团队索引为单独的文档。这可以通过循环遍历团队数组并在相同类型下索引每个团队(例如team_type)来完成。现在,在运行搜索查询时,您只会获得与查询匹配的团队文档。
2)将团队索引为父级内的嵌套文档。然后,您可以使用inner_hits功能将与查询匹配的嵌套文档作为inner_hit数组中的元素返回。此功能非常新,仅在新发布的Elasticsearch 1.5中可用。见这里:inner_hits
编辑:
使用如下映射创建一个新索引(将“index”和“type”更改为其他内容):
curl -XPOST 'http://localhost:9200/index/_mapping/type' -d '
{
"mapping": {
"properties": {
"point": {
"type": "String",
"index": "not_analyzed"
},
"homeTeam": {
"type": "String",
"index": "not_analyzed"
},
"awayTeam": {
"type": "String",
"index": "not_analyzed"
}
}
}
}'
curl -XPOST 'http://localhost:9200/index'
现在将代码更改为:
File jsonFile=new File("testmsg.txt");
try(InputStream is = new FileInputStream(jsonFile)) {
//read configuration from a JSON file
JsonNode node = new ObjectMapper().readTree(is);
if(node.get("markers").isArray()) {
ArrayNode arrayNode = (ArrayNode)node.get("markers");
arrayNode.elements().forEachRemaining(jnode -> {
if(jnode.isObject()) {
ObjectNode obj = (ObjectNode)jnode;
IndexResponse response = client.prepareIndex(index, type)
.setSource(obj.toString()).execute().actionGet();
}
});
}
}
catch(Exception e) {
e.printStackTrace();
}
您现在正在将数组的每个元素编入索引作为单独的文档。搜索特定的文件现在只会生成该特定文档。