在 Mapping 里面,将 dynamic 参数设置成 strict 可以拒绝索引包含未知字段的文档。 此条 Tips 由 medcl 贡献。

elasticSearch5.X javaAPI rangeQuery分区间查询,最终用了一种最low的方法凑合?不知大神们有没有好解决方案?

Elasticsearch | 作者 zlw7741 | 发布于2017年10月11日 | 阅读数:8764

age年龄(int类型)有0-100岁,比如我想查询20-30和40-50岁的人:
"range": {  
        "field": "age",  
        "ranges": [  
          {  
            "from": 20,  
            "to": 30  
          },  
          {  
            "from": 40,  
            "to": 50  
          }  
        ]  
      }
我首先想到的是这样:
BoolQueryBuilder bqb = QueryBuilders.boolQuery();
bqb.filter(QueryBuilders.rangeQuery("age").from(20).to(30).from(40).to(50));
SearchRequestBuilder setQuery = setTypes.setQuery(bqb);

这样查询出来的结果只有40-50。然后我换了一种方式:
BoolQueryBuilder bqb = QueryBuilders.boolQuery();
bqb.filter(QueryBuilders.rangeQuery("age").from(20).to(30));
bqb.filter(QueryBuilders.rangeQuery("age").from(40).to(50));
SearchRequestBuilder setQuery = setTypes.setQuery(bqb);

这种方式查出来的数据为null.fileter和must的结果是一样的,should会查询出0-100的年龄,并不是我想要的。
最后我用了mustnot:
BoolQueryBuilder bqb = QueryBuilders.boolQuery();
bqb.mustNot(QueryBuilders.rangeQuery("age").to(20));
bqb.mustNot(QueryBuilders.rangeQuery("age").from(30).to(40));
bqb.mustNot(QueryBuilders.rangeQuery("age").from(50));
SearchRequestBuilder setQuery = setTypes.setQuery(bqb);

数据达到了我的需求,但这样肯定是不对的。如果我不想要区间,想要21、31、41岁的数据,ES,javaapi怎么实现??...
 
已邀请:

kennywu76 - Wood

赞同来自: Cheetah linxiuyuan zlw7741

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.QueryBuilder;
import static org.elasticsearch.index.query.QueryBuilders.*;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class Main {
public static void main(String[] args) {
Settings settings = Settings.builder()
.put("cluster.name", "test")
.put("processors", 2)
.put("client.transport.sniff", true).build();

TransportClient client = new PreBuiltTransportClient(settings);

long stime = System.currentTimeMillis();
try {
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300));
} catch (UnknownHostException e) {
e.printStackTrace();
}
long etime=System.currentTimeMillis();
System.out.println("client instantiated in "+(etime-stime)+"ms");


// execute a search
QueryBuilder qb = boolQuery()
.should(rangeQuery("age").from("20").to("30"))
.should(rangeQuery("age").from("40").to("50"));
SearchResponse response = client.prepareSearch("twitter")
.setTypes("tweet")
.setQuery(qb)
.setFrom(0).setSize(60).setExplain(false)
.get();

System.out.println(response.toString());
}
}

 
client instantiated in 5157ms
{"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":3,"max_score":1.0,"hits":[{"_index":"twitter","_type":"tweet","_id":"5","_score":1.0,"_source":{"user": "Jan",
"age": "20"
}
},{"_index":"twitter","_type":"tweet","_id":"2","_score":1.0,"_source":{"user": "kenny",
"age": "41"
}
},{"_index":"twitter","_type":"tweet","_id":"3","_score":1.0,"_source":{"user": "allen",
"age": "20"
}
}]}}

Process finished with exit code 0

kennywu76 - Wood

赞同来自: zlw7741 vearne

@zlw7741  这个是因为你的bool逻辑组织得不对, 你需要像下面这样写:
QueryBuilder qb = boolQuery()
.must(boolQuery()
.should(rangeQuery("age").from("20").to("30"))
.should(rangeQuery("age").from("40").to("50")))
.must(termQuery("status1",1 ))
// 其他must .........

要回复问题请先登录注册