ElasticSearch Java API在文档中获取数组并应用过滤器并对

时间:2016-07-21 10:28:18

标签: java arrays sorting elasticsearch

我必须使用Java ES API编写一个复杂的查询,它将检索结果页面,进行排序和选项过滤。到目前为止,这是我在ElasticSearch中的映射:

{
    "mappings" : {
      "applications" : {
        "properties" : {
          "applications" : {
            "properties" : {
              "dynamicSize" : {
                "type" : "long"
              },
              "name" : {
                "type" : "string"
              },
              "packageName" : {
                "type" : "string"
              },
              "type" : {
                "type" : "string"
              },
              "updateTimestamp" : {
                "type" : "long"
              },
              "version" : {
                "type" : "string"
              }
            }
          },
          "imei" : {
            "type" : "string"
          },
          "timestamp" : {
            "type" : "long"
          }
        }
      }
    }
  }

基本上,我有一个包含IMEI(获取文档的密钥),时间戳和应用程序列表的文档。我想根据 imei 获取文档的最新时间戳的应用程序列表。我很难看到如何编写此查询。在Java中,我已经这样做了:

SortBuilder sortBuilder = SortBuilders.fieldSort(pageParameter.getOrderField()).order(pageParameter.getOrder());
SearchHit[] hitsArray = client.prepareSearch(index)
                .setTypes(type)
                .setQuery(termQueryBuilder)
                .setFrom(pageParameter.getFrom())
                .setSize(pageParameter.getSize())
                .setPostFilter(pageParameter.getFilters())
                .addSort(sortBuilder)
                .execute()
                .actionGet()
                .getHits()
                .getHits();

其中pageParameter对象包含要检索的当前页面(例如:0(页面1)),页面的大小(例如:25), sortOrder 和optionnal 过滤器的JSONObject。

此处的问题:

1-问题是我根据IMEI获取了我的文档,但排序顺序不起作用,因为它不查找“applications”数组中包含的字段。

我按排序顺序尝试将 applications.name ,asc像这样:

SortBuilder sortBuilder = SortBuilders.fieldSort("applications." + pageParameter.getOrderField()).order(pageParameter.getOrder());

我还在 setType()之后添加了方法 .addField(“applications”),因为我虽然会检索到我的列表,然后我可以申请我的分页和排序/过滤过程。 在调试中,我看到一切都好,sortBuilder包含“ applications.name ”作为排序依据的字段,“ asc ”作为订单

2-如果我得到多个相同的IMEI,我将为每个文档执行此操作,但我只想要最新的文档。

如果有人非常了解这个API,你能帮助我吗? 谢谢!

编辑:

我首先尝试使用REST请求来检查这是否可行。目前,我没有从想要的IMEI中对应用程序列表进行排序,过滤和分页。

我应用了以下映射:

{
    "mappings": {
        "applications": {
            "properties": {
                "imei": {
                    "index": "not_analyzed",
                    "type": "string"
                },
                "applications": {
                    "type": "nested",
                    "properties": {
                        "dynamicSize": {
                            "type": "long"
                        },
                        "name": {
                            "index": "not_analyzed",
                            "type": "string"
                        },
                        "packageName": {
                            "index": "not_analyzed",
                            "type": "string"
                        },
                        "type": {
                            "index": "not_analyzed",
                            "type": "string"
                        },
                        "version": {
                            "index": "not_analyzed",
                            "type": "string"
                        },
                        "updateTimestamp": {
                            "type": "long"
                        }
                    }
                },
                "timestamp": {
                    "type": "long"
                }
            }
        }
    }
}

在此之后,我尝试了不同的查询,例如:

TEST 1:

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "imei": "359678064430535"
          }
        }
      ]
    }
  },
  "filter": {
      "nested": {
          "path": "applications",
          "filter": {
              "term": {
                  "name" :"SoundAlive"
              }
          }
      }
  },
  "sort": [{
      "applications.name" : { "order" : "asc" }
  }],
  "inner_hits": {},
  "from": 0,
  "size": 5
}

测试2:

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "applications.imei": "359678064430535"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 10,
  "sort": [
    {
      "applications.name": {
        "order": "asc",
        "nested_path": "applications"
      }
    }
  ],
  "aggs": {}
}

TEST3:

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "imei": "359678064430535"
          }
        }
      ]
    }
  },
  "sort": [{
      "applications.name" : { "order" : "asc" }
  }],
  "from": 0,
  "size": 2,
  "fields": [ "applications.name" ]
}

在TEST 3中,我能够从object中包含的数组中检索所有的applications.name,但是我无法检索整个对象数组,也无法对其进行过滤或排序:(

编辑2:

我今天尝试了另一个问题:

{
  "query": {
     "filtered": {
        "query": {
            "match": { 
              "imei" : "359678064430535"
            }
        },
        "filter": {
            "nested": {
                "path": "applications",
                "query" : {
                    "match_all": { }
                },
                "filter": {
                    "and": [{
                        "term": {
                            "applications.name" : "myAppName"
                        }
                    }]
                }
            }
        }
      }
  }
}

但我不能对嵌套查询进行排序,结果似乎不敏感。我还是得到了完整的对象,不仅是应用程序列表......为什么这么难?它甚至可能吗?

0 个答案:

没有答案