java - Java 中的嵌套结果

标签 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。然后我尝试在“fixture”字段中搜索“Tuesday”一词。我找到了这个,但结果我得到了完整的“标记”列表,而不仅仅是第二个元素。我现在想知道我的方法有什么问题。

这是我的 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);
    }

如果能得到任何有关此问题的提示/帮助,那就太好了!

最佳答案

看起来 Jackson 将所有内容都放入一个 JSON 对象中。然后将其作为 Elasticsearch 中的单个文档进行索引。

运行查询时,Elasticsearch 始终返回完整文档作为结果。部分文件无法退回。因此,在运行查询时,将返回包含带有名为“Tuesday”的固定装置的元素的所有文档。由于您的单个文档包含星期三和星期二作为固定时间,因此即使您只搜索星期二,这两个元素也会返回。即使只有与“Tuesday”匹配的部分实际上与查询匹配,整个文档仍被返回。

以下章节是必读的: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();
}

您现在将数组的每个元素作为单独的文档进行索引。搜索特定文档现在只会产生该特定文档。

关于java - Java 中的嵌套结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29287652/

相关文章:

scala - Scala:使用Spark读取Elasticsearch中的数组值

java - 返回链表中的 (2n/3) 个元素,同时在链表上循环一次

java - 由 water.parser.ParseDataset$H2OParse 引起的 H2O h2o.importFile 错误 : 'Cannot determine file type. for nfs://.../model.zip' ,

java - setDefaultZoom(WebSettings.ZoomDensity.valueOf(arg0)) 的 arg0 是什么?

performance - Elasticsearch 索引性能调优

amazon-web-services - 向AWS ELB后面的所有计算机发送请求

elasticsearch - 源过滤不适用于 kibana

java - 圆形图标无法调整大小以适应屏幕

java - 结合Hive与Mahout进行推荐

couchdb - 使用CouchDB和Elasticsearch进行不同的选择