1.首先介绍一下ES的查询类型,SearchType。

    ES一共有四种查询类型:

QUERY_AND_FETCH:主节点将查询请求分发到所有的分片中,各个分片按照自己的查询规则即词频文档频率进行打分排序,然后将结果返回给主节点,主节点对所有数据进行汇总排序然后再返回给客户端,此种方式只需要和ES交互一次。
     特点:a.存在数据量和排序问题,主节点会汇总所有分片返回的数据,这样数据量会比较大b.各个分片上的规则可能不一致
    QUERY_THEN_FETCH:主节点将请求分发给所有分片,各个分片打分排序后将数据的id和分值返回给主节点,主节点收到后进行汇总排序,再根据排序后的id到对应的节点读取对应的数据再返回给客户端,此种方式需要和ES交互两次
     特点:解决了数据量问题但是排序问题依然存在,是ES的默认查询方式
    DFS_QUERY_AND_FETCH:和前面两种的区别在于将各个分片的规则统一起来进行打分
    特点:解决了排序问题,但是仍然存在数据量问题
    DFS_QUERY_THEN_FETCH:和前面两种的区别在于将各个分片的规则统一起来进行打分,将数据的id和分值返回给主节点,主节点收到后进行汇总排序,再根据排序后的id到对应的节点读取对应的数据再返回给客户端
    特点:解决了排序和数据量问题但是效率是最差的

2. 分页是会给服务器造成很大的压力。原因是会将分片的数据汇总后数据,如果有N个分片就会产生N倍的数量。

3.Java操作ES

依赖包:

 

<dependency>
         <groupId>org.elasticsearch</groupId>
         <artifactId>elasticsearch</artifactId>
         <version>2.4.1</version>
     </dependency>
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ExecutionException;

import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.get.MultiGetItemResponse;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.bucket.terms.Terms.Bucket;
import org.elasticsearch.search.aggregations.metrics.sum.Sum;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;

import com.alibaba.fastjson.JSON;


/**
 * Hello world!
 *
 */
public class App 
{
    private static TransportClient client;
    
    
    static {
        System.out.println("初始化链接。。。");
        Map<String, String> map = new HashMap<>();  
        map.put("cluster.name", "my_home");  
        Settings.Builder settings = Settings.builder().put(map);  
        
        try {
            client = TransportClient.builder().settings(settings).build()  
                            .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), Integer.parseInt("9300")));
            List<DiscoveryNode> nodes = client.connectedNodes();
            
            for (DiscoveryNode node : nodes) {
                System.out.println(node.getHostAddress());
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } 
    }
    
    
    public static void main(String[] args) throws Exception {
        testPreference();
    }
    
    /**
     * 功能描述: 增加索引
     * 
     * @throws Exception void
     * @version 1.0.6
     * @author king
     */
    public static void addIndex() throws Exception{
        System.out.println("============分=====割=====线=============");
        
        XContentBuilder source = createJson4();
        // 存json入索引中
        IndexResponse response = client.prepareIndex("twitter", "tweet", "4").setSource(source).get();
        // 结果获取
        String index = response.getIndex();
        String type = response.getType();
        String id = response.getId();
        long version = response.getVersion();
        boolean created = response.isCreated();
        
        Map<String, Object> result = new HashMap<>();
        result.put("index", index);
        result.put("type", type);
        result.put("id", id);
        result.put("version", version);
        result.put("created", created);
        
        System.out.println(JSON.toJSONString(result));
    }
    
    
    /**
     * 功能描述:删除索引 
     *  void
     * @version 1.0.6
     * @author king
     */
    public static void delIndex() {
        System.out.println("======================删==除===分===割==线=================");
        
        DeleteResponse deleteResponse = client.prepareDelete("twitter", "tweet", "1").get();
        String index = deleteResponse.getIndex();
        String type = deleteResponse.getType();
        String id = deleteResponse.getId();
        Long version = deleteResponse.getVersion();
        
        Map<String, Object> result = new HashMap<>();
        result.put("index", index);
        result.put("type", type);
        result.put("id", id);
        result.put("version", version);
        
        System.out.println(JSON.toJSONString(result));
    }
    
    
    
    /**
     * 功能描述: 获取数据
     *  void
     * @version 1.0.6
     * @author king
     */
    public static void getData() {
        System.out.println("=================获==取==数==据==============");
        GetResponse getResponse = client.prepareGet("tom", "cat", "2").execute().actionGet();
        String id = getResponse.getId();
        String resultStr = getResponse.getSourceAsString();
        System.out.println("id" + id);
        System.out.println("resultStr:" + resultStr);
    }
    
    
    /**
     * 
     * */   
    public static void testGetThread() {
        //设置线程安全
        GetResponse  getresponse = client.prepareGet("tom", "cat", "2").setOperationThreaded(false).get();
        System.out.println(getresponse.getSourceAsString());
    }
    
    
    
    /**
     * 功能描述: 更新ES数据
     * 
     * @throws IOException
     * @throws InterruptedException
     * @throws ExecutionException void
     * @version 1.0.6
     * @author king
     */
    public static void testUpdate() throws IOException, InterruptedException, ExecutionException {
        UpdateRequest updateRequest = new UpdateRequest();
        updateRequest.index("tom");
        updateRequest.type("cat");
        updateRequest.id("2");
        updateRequest.doc(XContentFactory.jsonBuilder()
                .startObject()
                .field("phone", "17686886688")
                .field("color", "blue")
                .endObject());
        
        UpdateResponse updateResponse = client.update(updateRequest).get();
        String index = updateResponse.getIndex();
        String type = updateResponse.getType();
        String id = updateResponse.getId();
        long version = updateResponse.getVersion();
        
        Map<String, Object> result = new HashMap<>();
        result.put("index", index);
        result.put("type", type);
        result.put("id", id);
        result.put("version", version);
        
        System.out.println(JSON.toJSONString(result));
    }
    
    
    /**
     * 功能描述: 更新数据
     * 
     * @throws IOException
     * @throws InterruptedException
     * @throws ExecutionException void
     * @version 1.0.6
     * @author yaoyaowang
     */
    public static void testUpdate1() throws IOException, InterruptedException, ExecutionException {
        UpdateRequest updateRequest = new UpdateRequest("tom", "cat", "2");
        updateRequest.doc(XContentFactory.jsonBuilder()
                .startObject()
                .field("phone", "1366688866")
                .endObject());
        
        UpdateResponse updateResponse = client.update(updateRequest).get();
        String index = updateResponse.getIndex();
        String type = updateResponse.getType();
        String id = updateResponse.getId();
        long version = updateResponse.getVersion();
        
        Map<String, Object> result = new HashMap<>();
        result.put("index", index);
        result.put("type", type);
        result.put("id", id);
        result.put("version", version);
        
        System.out.println(JSON.toJSONString(result));
    }
    
    
    /**
     * 功能描述: 新增数据,如果没有插入,如果有更新
     * 
     * @throws IOException
     * @throws InterruptedException
     * @throws ExecutionException void
     * @version 1.0.6
     * @author yaoyaowang
     */
    public static void testUpSert() throws IOException, InterruptedException, ExecutionException {
        //查询该数据是否存在,如果不存在则插入
        IndexRequest indexRequest = new IndexRequest("tom", "cat", "1");
        indexRequest.source(XContentFactory.jsonBuilder()
                .startObject()
                .field("name", "staven")
                .field("id", "2")
                .field("age", "20")
                .field("sex", "F")
                .field("address", "America")
                .field("phone", "110")
                .field("color", "yello"));
        
        //更新该数据,看该数据是否存在,如果不存在,则把上面的数据插入,如果存在则把数据更新(将"address", "America" 更新为 "address", "America")
        UpdateRequest updateRequest = new UpdateRequest("tom", "cat", "1");
        updateRequest.doc(XContentFactory.jsonBuilder()
                .startObject()
                .field("address", "America")
                .endObject());
        updateRequest.upsert(indexRequest);
        
        UpdateResponse updateResponse = client.update(updateRequest).get();
        
        String index = updateResponse.getIndex();
        String type = updateResponse.getType();
        String id = updateResponse.getId();
        long version = updateResponse.getVersion();
        
        Map<String, Object> result = new HashMap<>();
        result.put("index", index);
        result.put("type", type);
        result.put("id", id);
        result.put("version", version);
        
        System.out.println(JSON.toJSONString(result));        
    }
    
    
    /**
     * 功能描述: 增加索引
     *  void
     * @version 1.0.6
     * @author king
     */
    public static void testMultiGet() {
        MultiGetResponse multiGetResponse = client.prepareMultiGet()
            .add("tom", "cat", "1")
            .add("tom", "cat", "2")
            .add("twitter", "tweet", "1")
            .get();
        
        for(MultiGetItemResponse itemReponse : multiGetResponse){
            GetResponse getResponse = itemReponse.getResponse();
            if(getResponse.isExists()){
                String sourceAsString = getResponse.getSourceAsString();
                System.out.println(sourceAsString);
            }
        }
        
    }
    
    
    /**
     * 功能描述: 批处理
     * 
     * @throws Exception void
     * @version 1.0.6
     * @author yaoyaowang
     */
    public static void testBulk() throws Exception {
        BulkRequestBuilder bulkBuilder = client.prepareBulk();
        bulkBuilder.add(client.prepareIndex("tom", "cat", "3")
                .setSource(XContentFactory.jsonBuilder()
                        .startObject()
                        .field("id", "2")
                        .field("name", "rose")
                        .field("age", "18")
                        .field("sex", "F")
                        .field("address", "tianjin")
                        .field("color", "black")
                        .field("phone", "120")
                        .endObject()));
        
        bulkBuilder.add(client.prepareIndex("tom", "cat", "1")
                .setSource(XContentFactory.jsonBuilder()
                        .startObject()
                        .field("address", "England")
                        .endObject()));
        
        BulkResponse bulkResponse = bulkBuilder.get();
        System.out.println(bulkResponse.getHeaders());
    }
    
    
    /**
     * 功能描述: 统计索引下的数据
     *  void
     * @version 1.0.6
     * @author king
     */  
    public static void testCount(){
        long num = client.prepareCount("twitter").get().getCount();
        System.out.println(String.format("twitter的总数为:%d", num));
    }
    
    
    /**
     * 功能描述: 查询
     * 
     *  void
     * @version 1.0.6
     * @author king
     */
    public static void testSearch() {
        Map<String, String> query = new HashMap<>();
        query.put("name", "tom");
        SearchResponse searchResponse  = client.prepareSearch("twitter").setTypes("tweet")
            //.setQuery(QueryBuilders.matchQuery("name", "tom").operator(Operator.AND)).setSearchType(SearchType.DEFAULT)
            .setFrom(0).setSize(2).addSort("id", SortOrder.DESC)
            .get();
        
        SearchHits searchHits = searchResponse.getHits();
        Long count = searchHits.getTotalHits();
        System.out.println("总数:" + count);
        SearchHit[] searchHitArr = searchHits.getHits();
        for(SearchHit searchHit : searchHitArr){
            System.out.println(searchHit.getSourceAsString());
        }
    }
    
    
    /**
     * 功能描述: 筛选
     *  void
     * @version 1.0.6
     * @author king
     */
    public static void testFilter() {
        SearchResponse searchResponse = client.prepareSearch("twitter").setTypes("tweet")
            .setQuery(QueryBuilders.matchAllQuery())
            .setPostFilter(QueryBuilders.rangeQuery("age").gte(17))
            .setFrom(0).addSort("id", SortOrder.ASC)
            .get();
        
        SearchHits searchHits = searchResponse.getHits();
        Long total = searchHits.getTotalHits();
        System.out.println("年龄大于17的数据总数" + total);
        SearchHit[] searchHitArr = searchHits.getHits();
        for(SearchHit searchHit : searchHitArr){
            System.out.println(searchHit.getSourceAsString());
        }
    }
    
    
    /**
     * 功能描述: 高亮
     *  void
     * @version 1.0.6
     * @author king
     */
    public static void testHighLight() {
        SearchResponse searchResponse = client.prepareSearch("twitter").setTypes("tweet")
            .setQuery(QueryBuilders.matchQuery("name", "tom"))
            .setSearchType(SearchType.QUERY_THEN_FETCH)
            .addHighlightedField("name")
            .setHighlighterPreTags("<font color='red'>")
            .setHighlighterPostTags("</font>")
            .get();
        
        SearchHits searchHits = searchResponse.getHits();
        long total = searchHits.getTotalHits();
        System.out.println("索引twitter下的所有数据的总数:" + total);
        SearchHit[] searchHitArr = searchHits.getHits();
        for(SearchHit searchHit : searchHitArr){
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            HighlightField highlightField = highlightFields.get("name");
            if(null != highlightField){
                Text[] fragments = highlightField.fragments();
                System.out.println("这是个什么鬼呢? ---> " + fragments[0]);
            }
            
            System.out.println(searchHit.sourceAsString());
        } 
    }
    
    
    
    /**
     * 功能描述: 分组统计
     *  void
     * @version 1.0.6
     * @author king
     */
    public static void testGroupBy() {
        SearchResponse searchResponse = client.prepareSearch("twitter").setTypes("tweet")
            .setQuery(QueryBuilders.matchAllQuery())
            .setSearchType(SearchType.QUERY_THEN_FETCH)
            .addAggregation(AggregationBuilders.terms("group_age").field("age").size(0))
            .get();
        
        Terms terms = searchResponse.getAggregations().get("group_age");
        List<Bucket> buckets = terms.getBuckets();
        for(Bucket bucket : buckets){
            System.out.println(bucket.getKey() + ":" + bucket.getDocCount());
        }
    }
    
    
    
    
    /**
     * 功能描述: 聚合
     *  void
     * @version 1.0.6
     * @author king
     */
    public static void testAggregationFunction() {
        SearchResponse searchResponse = client.prepareSearch("twitter").setTypes("tweet")
            .setQuery(QueryBuilders.matchAllQuery())
            .setSearchType(SearchType.QUERY_THEN_FETCH)
            .addAggregation(AggregationBuilders.terms("group_name").field("name")
                    .subAggregation(AggregationBuilders.sum("age_count").field("age")))
            .get();
            
        Terms terms = searchResponse.getAggregations().get("group_name");
        List<Bucket> buckets = terms.getBuckets();
        for(Bucket bucket : buckets){
            Sum sum = bucket.getAggregations().get("age_count");
            System.out.println("{" + bucket.getKey() + ":" + bucket.getDocCount() + ":" + sum.getValue() + "}");
        }
    }
    
    
    
    /**
     * 功能描述: 造数据
     * 
     * @throws IOException void
     * @version 1.0.6
     * @author king
     */
    public static void generateOtherIndexData() throws IOException {
        for(int i = 1; i <= 60; i++){
            XContentBuilder source = XContentFactory.jsonBuilder()
                    .startObject()
                        .field("id", i)
                        .field("name", createName())
                        .field("sex", (i < 30 ? "F" : "M"))
                        .field("age", createAge())
                        .field("address", "china")
                    .endObject();
            
            client.prepareIndex("ycu", "computer", String.valueOf(i-1)).setSource(source).get(); 
        }
    }
    
    
    
    /**
     * 功能描述: 创建人名
     * 
     * @return String
     * @version 1.0.6
     * @author king
     */
    public static String createName(){
        Random random = new Random();
        String[] str = {"q","w","e","r","t","y","u","i","o","p","a","s","f","d","g","h","j","k","l","z","x","c","v","b","n","m"};
        random.nextInt(23);
        String name = new StringBuffer(str[random.nextInt(23)]).append(str[random.nextInt(23)])
                .append(str[random.nextInt(23)]).toString();
        return name;
    }
    
    /**
     * 功能描述: 创建年龄
     * 
     * @return int
     * @version 1.0.6
     * @author king
     */
    public static int createAge(){
        Random random = new Random();
        String[] num = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
        String ageStr = new StringBuffer(num[random.nextInt(10)]).append(num[random.nextInt(10)]).toString();
        return Integer.parseInt(ageStr);       
    }
    
    
    /**
     * 功能描述: 指定分片区查询数据
     *  void
     * @version 1.0.6
     * @author king
     */
    public static void testPreference(){
        SearchResponse searchResponse = client.prepareSearch("ycu").setTypes("computer").setPreference("_shards:0,1")
            .setQuery(QueryBuilders.matchAllQuery()).setExplain(true).setFrom(0).setSize(60).get();
        
        SearchHits searchHits = searchResponse.getHits();
        long total = searchHits.getTotalHits();
        SearchHit[] searchHitArr = searchHits.getHits();
        System.out.println("总数:" + total);
        for(SearchHit searchHit : searchHitArr){
            System.out.println(searchHit.getSourceAsString());
        }
    }
    
    
    
    
    
    /**
     * 使用es的帮助类
     */
    public static XContentBuilder createJson4() throws Exception {
        // 创建json对象, 其中一个创建json的方式
        XContentBuilder source = XContentFactory.jsonBuilder()
            .startObject()
                .field("id", "5")
                .field("name", "tom")
                .field("sex", "F")
                .field("age", 19)
                .field("address", "china")
            .endObject();
        return source;
    }
}