Java中的嵌套结果

时间:2015-03-26 19:55:45

标签: java elasticsearch

我正在尝试在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);
    }

对此有任何提示/帮助会很棒!

1 个答案:

答案 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();
}

您现在正在将数组的每个元素编入索引作为单独的文档。搜索特定的文件现在只会生成该特定文档。