package com.elab.example.springbootdemo.es;

import com.elab.es.client.DefaultElasticSearchTemplate;
import com.elab.example.springbootdemo.SpringbootDemoApplication;
import com.elab.example.springbootdemo.es.entity.User;
import com.elab.example.springbootdemo.es.entity.UserTable;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.*;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.zxp.esclientrhl.repository.HighLight;
import org.zxp.esclientrhl.repository.PageList;
import org.zxp.esclientrhl.repository.PageSortHighLight;
import org.zxp.esclientrhl.repository.Sort;
import org.zxp.esclientrhl.util.JsonUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @author ： liukx
 * @time ： 2019/8/1 - 11:40
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {SpringbootDemoApplication.class})
public class EsTest {

    private Logger logger = LoggerFactory.getLogger(EsTest.class);

    @Autowired
    private DefaultElasticSearchTemplate<User, String> elasticsearchTemplate;

    @Autowired
    private DefaultElasticSearchTemplate<UserTable, String> elasticsearchTemplate1;

    @Test
    public void save() throws Exception {
        User user = new User();
        user.setMessage("新的测试");
        user.setPostDate(new Date());
        user.setUser("某某某");
        user.setId(UUID.randomUUID().toString());

        IndexRequest request = new IndexRequest();
        request.setPipeline("");

        boolean save = elasticsearchTemplate.save(user);
        logger.info(" 结果 : " + save);
    }

    @Test
    public void update() throws Exception {
        User user = getUser("新的测试1111", "周杰伦2");
//        boolean save = elasticsearchTemplate.update(user);
        boolean save = elasticsearchTemplate.updateCover(user);
        logger.info(" 结果 : " + save);
    }

    private User getUser(String mesage, String username) {
        User user = new User();
        user.setMessage(mesage);
        user.setPostDate(new Date());
        user.setUser(username);
        user.setId(UUID.randomUUID().toString());
        return user;
    }

    private UserTable getUserTable(String mesage, String username) {
        UserTable user = new UserTable();
        user.setMessage(mesage);
        user.setPostDate(new Date());
        user.setTitle(mesage);
        user.setDoc_id(UUID.randomUUID().toString());
        return user;
    }

    @Test
    public void delete() throws Exception {
        boolean b = elasticsearchTemplate.deleteById("633b5f31-8cfd-47d4-bc9a-a151fb23633f", User.class);
        logger.info(" result : " + b);
    }

    @Test
    public void msave() throws Exception {
        List<UserTable> list = new ArrayList<>();
        int i = 1001;
        list.add(getUserTable("双卧朝南向 高层视野开阔 客厅挂东窗 居住舒适", "周杰伦" + i++));
        list.add(getUserTable("高层观三大公园三居室，安静不临街，精装修智能家居", "周杰伦" + i++));
        list.add(getUserTable("馨莲茗园精装南北通透三居室 满五年唯一 看房方便", "周杰伦" + i++));
        list.add(getUserTable("次顶层，视野好，人车分流，满五唯一，南北通透", "周杰伦" + i++));
        list.add(getUserTable("万科星园南北3居2卫观奥森公园，满五年仅有住房", "周杰伦" + i++));
        list.add(getUserTable("南北通透三居室   中间楼层  采光无遮挡", "周杰伦" + i++));
        list.add(getUserTable("6号楼一梯两户安静位置南北向三居，金地物业", "周杰伦" + i++));
        list.add(getUserTable("南北双通透两梯两户 眼睛户型中间楼层", "周杰伦" + i++));
        list.add(getUserTable("南北正规三居 观花园 安静位置 板楼 带明卫 税费少", "周杰伦" + i++));
        list.add(getUserTable("风格雅园 低密度社区 双卧朝南三居室", "周杰伦" + i++));
        list.add(getUserTable("南北通透普通住宅正规三居，低密度封闭式管理", "周杰伦" + i++));
        list.add(getUserTable("双井合生国际高层南北通透观景三居室", "周杰伦" + i++));
        list.add(getUserTable("满五年唯一，业主自住房二次装修；双明卫户型！", "周杰伦" + i++));
        list.add(getUserTable("70年产权东城区东直门桥东南角东方银座三居室", "周杰伦" + i++));
        list.add(getUserTable("海淀金玉府 南北三居室 高楼层视野开阔", "周杰伦" + i++));
        list.add(getUserTable("新上三居，南北通透不临街，满五年唯一", "周杰伦" + i++));
        list.add(getUserTable("金都杭城东区 3室2厅 1090万", "周杰伦" + i++));
        list.add(getUserTable("万科中粮假日风景 3室1厅 1050万", "周杰伦" + i++));
        list.add(getUserTable("海淀2005年，中国房子，首套购房1.5%契税，南北3居室", "周杰伦" + i++));
        list.add(getUserTable("一层带花园，不临街，满五年唯一，精装修，看房方便", "周杰伦" + i++));
        list.add(getUserTable("中国房子 3室2厅 1025万", "周杰伦" + i++));
        list.add(getUserTable("山水文园 三面采光 南北通透的三居室", "周杰伦" + i++));
        list.add(getUserTable("带车位看房有钥匙前后不临街对花园", "周杰伦" + i++));
        list.add(getUserTable("五星必看好房乐成国际270度采光三居金地物业满五唯一", "周杰伦" + i++));
        list.add(getUserTable("九台东南三居 全明格局 随时看房", "周杰伦" + i++));
        list.add(getUserTable("南北正规三居户型，带储藏间，精装修", "周杰伦" + i++));
        list.add(getUserTable("千鹤家园正规西南向三居室，满五年唯一", "周杰伦" + i++));
        list.add(getUserTable("二期园林！满五年唯一！只需契税！南北通透！板楼！", "周杰伦" + i++));
        list.add(getUserTable("此房满五年唯一，配套齐全，交通便利，前后不临街", "周杰伦" + i++));
        list.add(getUserTable("融科三期双卧朝南三居 双通透 满五唯一飘窗不算面积", "周杰伦" + i++));
        list.add(getUserTable("西南北朝向，三居室，购房税费少", "周杰伦" + i++));
        list.add(getUserTable("金星园南北通透三居室满五年唯一住房", "周杰伦" + i++));
        list.add(getUserTable("2004年航天部分房，华润物业，西南北向，两卫，采光好", "周杰伦" + i++));
        list.add(getUserTable("太阳公元南区A类全新三居  南北通透  百米楼间距", "周杰伦" + i++));
        list.add(getUserTable("满五唯一东西通透三居室，业主诚心卖", "周杰伦" + i++));
        list.add(getUserTable("金隅丽港城 低密板楼户型好带私密花园车位 品质住房", "周杰伦" + i++));
        list.add(getUserTable("央产房次顶层 东观玉渊潭 西眺妙峰山 半个北京城视野", "周杰伦" + i++));
        list.add(getUserTable("和平西桥 楼龄新 东南三居室 满五年唯一 无遮挡视野佳", "周杰伦" + i++));
        list.add(getUserTable("南北通透3居 明厨明卫  精装修不临街", "周杰伦" + i++));
        list.add(getUserTable("远中悦莱东南向大三居 满两年原值高税费少", "周杰伦" + i++));
        BulkResponse save = elasticsearchTemplate1.save(list);
        RestStatus status = save.status();
        logger.info(status.toString());

    }


    @Test
    public void search() throws Exception {
        SearchRequest searchRequest = new SearchRequest(new String[]{"posts"});
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(new MatchAllQueryBuilder());
        searchSourceBuilder.from(0);
        searchSourceBuilder.size(10);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = elasticsearchTemplate.search(searchRequest);

        SearchHits hits = searchResponse.getHits();
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            User t = JsonUtils.string2Obj(hit.getSourceAsString(), User.class);
            System.out.println(t + "\t" + hit.getId());
        }
    }


    @Test
    public void search1() throws Exception {
        List<User> main2List = elasticsearchTemplate.search(new MatchAllQueryBuilder(), User.class);
        main2List.forEach(main2 -> System.out.println(main2));
    }


    @Test
    public void searchPage() throws Exception {
        //定制分页信息
        int currentPage = 1;
        int pageSize = 2;
        //分页
        PageSortHighLight psh = new PageSortHighLight(currentPage, pageSize);
        //排序字段，注意如果proposal_no是text类型会默认带有keyword性质，需要拼接.keyword
        String sorter = "postDate.keyword";
        Sort.Order order = new Sort.Order(SortOrder.ASC, sorter);
        psh.setSort(new Sort(order));
        //定制高亮，如果定制了高亮，返回结果会自动替换字段值为高亮内容
        HighLight highLight = new HighLight();
        //可以单独定义高亮的格式
        highLight.setPreTag("<em>");
        highLight.setPostTag("</em>");
        highLight.field("title");
        psh.setHighLight(highLight);
        PageList<UserTable> pageList = new PageList<>();
//        QueryBuilder queryBuilder = QueryBuilders.termQuery("user.keyword", "周杰伦2");
//        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("_all", "唯一");

        MultiMatchQueryBuilder matchQueryBuilder = QueryBuilders.multiMatchQuery("wy","title","message");
        pageList = elasticsearchTemplate1.search(matchQueryBuilder, psh, UserTable.class);
        pageList.getList().forEach(main2 -> System.out.println(main2.toString()));

    }

    @Test
    public void searchByField() throws Exception {
        List<String> list = elasticsearchTemplate.completionSuggest("user", "周杰伦", User.class);
        list.forEach(main2 -> System.out.println(main2));
    }

    @Test
    public void searchById() throws Exception {
        User main2 = elasticsearchTemplate.getById("f5fd0129-0b02-4685-b9f0-024b7ed48868", User.class);
        System.out.println(main2);
    }

    @Test
    public void searchByName() throws Exception {
        // 精准查询
        QueryBuilder queryBuilder = QueryBuilders.termQuery("user.keyword", "周杰伦2");
        // 短语查询
//        QueryBuilder queryBuilder = QueryBuilders.matchPhraseQuery("user", "2");
        // 移动匹配次数 slop设置为2，周[杰伦]2最多能移动两次并完成匹配
//        QueryBuilder queryBuilder = QueryBuilders.matchPhraseQuery("user","周2").slop(2);
        // 范围查询
        //  QueryBuilder queryBuilder = QueryBuilders.rangeQuery("postDate").from(1564639725110l).to(1564640107682l);

        //全文匹配
//        QueryBuilder queryBuilder = QueryBuilders.matchQuery("user", "周1");

        // minimumShouldMatch最少匹配参数
//        QueryBuilder queryBuilder = QueryBuilders.matchQuery("message", "业主").minimumShouldMatch("100%");

        // 纠错查询  需要集成fuzzy
//        QueryBuilder queryBuilder = QueryBuilders.matchQuery("message","明园");
//        ((MatchQueryBuilder) queryBuilder).fuzziness(Fuzziness.AUTO);


        // match设定逻辑关系，
//        QueryBuilder queryBuilder = QueryBuilders.matchQuery("message","yezhu").operator(Operator.AND);
//        MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("message", "yezhu").analyzer("my_pinyin");

        List<User> list = elasticsearchTemplate.search(queryBuilder, User.class);
        list.forEach(main2 -> System.out.println(main2));
    }

    @Test
    public void searchByName1() throws Exception {

        MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("message", "唯一").analyzer("my_pinyin");

        List<UserTable> list = elasticsearchTemplate1.search(queryBuilder, UserTable.class);
        list.forEach(main2 -> System.out.println(main2));

    }


}
