我必须使用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"
}
}]
}
}
}
}
}
}
但我不能对嵌套查询进行排序,结果似乎不敏感。我还是得到了完整的对象,不仅是应用程序列表......为什么这么难?它甚至可能吗?