package org.jeecg.modules.dataVue.controller;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.mchange.lang.DoubleUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.annotation.Obsolete;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.index.MultiReader;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Fragmenter;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.dataVue.entity.Content;
import org.jeecg.modules.dataVue.service.ILjrbService;
import org.jeecg.modules.dataVue.service.IZjfzService;
import org.jeecg.modules.dataVue.service.MyIKAnalyzer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/dataVue/lucene")
public class LuceneController {
    @Autowired
    IZjfzService iZjfzService;
    @Autowired
    ILjrbService iLjrbService;

    String getLucenePath() {
        String temp = ClassUtils.getDefaultClassLoader().getResource("").getPath();
        return System.getProperty("user.dir") + "\\lucene";
    }

    // region
    @RequestMapping(value = "/createIndex", method = RequestMethod.GET)
    @Obsolete
    public String createIndex() throws IOException {
        // region
        List<Content> list1 = new ArrayList<>();
        list1.add(new Content(null, "Java面向对象", "10", null, "Java面向对象从入门到精通,简单上手"));
        list1.add(new Content(null, "Java面向对象java", "10", null, "Java面向对象从入门到精通,简单上手"));
        list1.add(new Content(null, "Java面向编程", "15", null, "Java面向对象编程书籍"));
        list1.add(new Content(null, "JavaScript入门", "18", null, "JavaScript入门编程书籍"));
        list1.add(new Content(null, "深入理解Java编程", "13", null, "十三四天掌握Java基础"));
        list1.add(new Content(null, "从入门到放弃_Java", "20", null, "一门从入门到放弃的书籍"));
        list1.add(new Content(null, "Head First Java", "30", null, "《Head First Java》是一本完整地面向对象(object-oriented，OO)程序设计和Java的学习指导用书"));
        list1.add(new Content(null, "Java 核心技术：卷1 基础知识", "22", null, "全书共14章，包括Java基本的程序结构、对象与类、继承、接口与内部类、图形程序设计、事件处理、Swing用户界面组件"));
        list1.add(new Content(null, "Java 编程思想", "12", null, "本书赢得了全球程序员的广泛赞誉，即使是最晦涩的概念，在Bruce Eckel的文字亲和力和小而直接的编程示例面前也会化解于无形"));
        list1.add(new Content(null, "Java开发实战经典", "51", null, "本书是一本综合讲解Java核心技术的书籍，在书中使用大量的代码及案例进行知识点的分析与运用"));
        list1.add(new Content(null, "Effective Java", "10", null, "本书介绍了在Java编程中57条极具实用价值的经验规则，这些经验规则涵盖了大多数开发人员每天所面临的问题的解决方案"));
        list1.add(new Content(null, "分布式 Java 应用：基础与实践", "14", null, "本书介绍了编写分布式Java应用涉及的众多知识点，分为了基于Java实现网络通信、RPC;基于SOA实现大型分布式Java应用"));
        list1.add(new Content(null, "http权威指南", "11", null, "超文本传输协议(Hypertext Transfer Protocol，HTTP)是在万维网上进行通信时所使用的协议方案"));
        list1.add(new Content(null, "Spring", "15", null, "这是啥，还需要学习吗？Java程序员必备书籍"));
        list1.add(new Content(null, "深入理解 Java 虚拟机", "18", null, "作为一位Java程序员，你是否也曾经想深入理解Java虚拟机，但是却被它的复杂和深奥拒之门外"));
        list1.add(new Content(null, "springboot实战", "11", null, "完成对于springboot的理解，是每个Java程序员必备的姿势"));
        list1.add(new Content(null, "springmvc学习", "72", null, "springmvc学习指南"));
        list1.add(new Content(null, "vue入门到放弃", "20", null, "vue入门到放弃书籍信息"));
        list1.add(new Content(null, "vue入门到精通", "20", null, "vue入门到精通相关书籍信息"));
        list1.add(new Content(null, "vue之旅", "20", null, "由浅入深地全面介绍vue技术，包含大量案例与代码"));
        list1.add(new Content(null, "vue实战", "20", null, "以实战为导向，系统讲解如何使用 "));
        list1.add(new Content(null, "vue入门与实践", "20", null, "现已得到苹果、微软、谷歌等主流厂商全面支持"));
        list1.add(new Content(null, "Vue.js应用测试", "20", null, "Vue.js创始人尤雨溪鼎力推荐！Vue官方测试工具作者亲笔撰写，Vue.js应用测试完全学习指南"));
        list1.add(new Content(null, "PHP和MySQL Web开发", "20", null, "本书是利用PHP和MySQL构建数据库驱动的Web应用程序的权威指南"));
        list1.add(new Content(null, "Web高效编程与优化实践", "20", null, "从思想提升和内容修炼两个维度，围绕前端工程师必备的前端技术和编程基础"));
        list1.add(new Content(null, "Vue.js 2.x实践指南", "20", null, "本书旨在让初学者能够快速上手vue技术栈，并能够利用所学知识独立动手进行项目开发"));
        list1.add(new Content(null, "初始vue", "20", null, "解开vue的面纱"));
        list1.add(new Content(null, "什么是vue", "20", null, "一步一步的了解vue相关信息"));
        list1.add(new Content(null, "深入浅出vue", "20", null, "深入浅出vue，慢慢掌握"));
        list1.add(new Content(null, "三天vue实战", "20", null, "三天掌握vue开发"));
        list1.add(new Content(null, "不知火舞", "20", null, "不知名的vue"));
        list1.add(new Content(null, "娜可露露", "20", null, "一招秒人"));
        list1.add(new Content(null, "宫本武藏", "20", null, "我就是一个超级兵"));
        list1.add(new Content(null, "vue宫本vue", "20", null, "我就是一个超级兵"));
        // endregion

        // 创建文档的集合
        Collection<Document> docs = new ArrayList<>();
        for (int i = 0; i < list1.size(); i++) {
            //contentMapper.insertSelective(list1.get(i));
            // 创建文档对象
            Document document1 = new Document();
            //StringField会创建索引，但是不会被分词，TextField，即创建索引又会被分词。
            document1.add(new StringField("id", (i + 1) + "", Field.Store.YES));

            document1.add(new TextField("title", list1.get(i).getTitle(), Field.Store.YES));
            document1.add(new TextField("price", list1.get(i).getPrice(), Field.Store.YES));
            document1.add(new TextField("descs", list1.get(i).getDescs(), Field.Store.YES));
            docs.add(document1);
        }

        // 索引目录类,指定索引在硬盘中的位置，我的设置为D盘的indexDir文件夹
        Directory directory = FSDirectory.open(FileSystems.getDefault().getPath(getLucenePath()));
        // 引入IK分词器
        Analyzer analyzer = new MyIKAnalyzer();
        // 索引写出工具的配置对象，这个地方就是最上面报错的问题解决方案
        IndexWriterConfig conf = new IndexWriterConfig(analyzer);
        // 设置打开方式：OpenMode.APPEND 会在索引库的基础上追加新索引。OpenMode.CREATE会先清空原来数据，再提交新的索引
        conf.setOpenMode(IndexWriterConfig.OpenMode.CREATE);
        // 创建索引的写出工具类。参数：索引的目录和配置信息
        IndexWriter indexWriter = new IndexWriter(directory, conf);
        // 把文档集合交给IndexWriter
        indexWriter.addDocuments(docs);
        // 提交
        indexWriter.commit();
        // 关闭
        indexWriter.close();
        return "success";
    }

    @RequestMapping("/updateIndex")
    @ResponseBody
    @Obsolete
    public String update(String age) throws IOException {
//        // 创建目录对象
//        Directory directory = FSDirectory.open(FileSystems.getDefault().getPath("d:\\indexDir"));
//        // 创建配置对象
//        IndexWriterConfig conf = new IndexWriterConfig(new MyIKAnalyzer());
//        // 创建索引写出工具
//        IndexWriter writer = new IndexWriter(directory, conf);
//        // 创建新的文档数据
//        Document doc = new Document();
//        doc.add(new StringField("id","34",Store.YES));
//        Content content = contentMapper.selectByPrimaryKey("34");
//        content.setTitle("宫本武藏超级兵");
//        contentMapper.updateByPrimaryKeySelective(content);
//        doc.add(new TextField("title", content.getTitle(), Field.Store.YES));
//        doc.add(new TextField("price", content.getPrice(), Field.Store.YES));
//        doc.add(new TextField("descs", content.getDescs(), Field.Store.YES));
//        writer.updateDocument(new Term("id","34"), doc);
//        // 提交
//        writer.commit();
//        // 关闭
//        writer.close();
        return "success";
    }

    @RequestMapping("/deleteIndex")
    @ResponseBody
    @Obsolete
    public String deleteIndex() throws IOException {
//        // 创建目录对象
//        Directory directory = FSDirectory.open(FileSystems.getDefault().getPath("d:\\indexDir"));
//        // 创建配置对象
//        IndexWriterConfig conf = new IndexWriterConfig(new IKAnalyzer());
//        // 创建索引写出工具
//        IndexWriter writer = new IndexWriter(directory, conf);
//        // 根据词条进行删除
//        writer.deleteDocuments(new Term("id", "34"));
//        // 提交
//        writer.commit();
//        // 关闭
//        writer.close();
        return "success";
    }

    public String searchText(String text, HttpServletRequest request) throws IOException, ParseException {
        Directory directory = FSDirectory.open(FileSystems.getDefault().getPath(getLucenePath()));
        // 索引读取工具
        IndexReader reader = DirectoryReader.open(directory);
        // 索引搜索工具
        IndexSearcher searcher = new IndexSearcher(reader);
        // 创建查询解析器,两个参数：默认要查询的字段的名称，分词器
        QueryParser parser = new QueryParser("descs", new MyIKAnalyzer());
        // 创建查询对象
        Query query = parser.parse(text);
        // 获取前十条记录
        TopDocs topDocs = searcher.search(query, 10);
        // 获取总条数
        System.out.println("本次搜索共找到" + topDocs.totalHits + "条数据");
        // 获取得分文档对象（ScoreDoc）数组.SocreDoc中包含：文档的编号、文档的得分
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        List<Content> list = new ArrayList<>();
        for (ScoreDoc scoreDoc : scoreDocs) {
            // 取出文档编号
            int docID = scoreDoc.doc;
            // 根据编号去找文档
            Document doc = reader.document(docID);
            Content content = new Content();//contentMapper.selectByPrimaryKey(doc.get("id"));
            list.add(content);
        }
        request.setAttribute("list", list);
        return "index";
    }

    // 多字段查询
    @RequestMapping("/searchText1")
    @Obsolete
    public String searchText1(String text, HttpServletRequest request) throws IOException, ParseException {
        Directory directory = FSDirectory.open(FileSystems.getDefault().getPath(getLucenePath()));
        // 索引读取工具
        IndexReader reader = DirectoryReader.open(directory);
        // 索引搜索工具
        IndexSearcher searcher = new IndexSearcher(reader);
        String[] str = {"title", "descs"};
        // 创建查询解析器,两个参数：默认要查询的字段的名称，分词器
        MultiFieldQueryParser parser = new MultiFieldQueryParser(str, new MyIKAnalyzer());
        // 创建查询对象
        Query query = parser.parse(text);
        // 获取前十条记录
        TopDocs topDocs = searcher.search(query, 100);
        // 获取总条数
        System.out.println("本次搜索共找到" + topDocs.totalHits + "条数据");
        // 获取得分文档对象（ScoreDoc）数组.SocreDoc中包含：文档的编号、文档的得分
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        List<Content> list = new ArrayList<>();
        for (ScoreDoc scoreDoc : scoreDocs) {
            // 取出文档编号
            int docID = scoreDoc.doc;
            // 根据编号去找文档
            Document doc = reader.document(docID);
            Content content = new Content();//contentMapper.selectByPrimaryKey(doc.get("id"));
            list.add(content);
        }
        request.setAttribute("list", list);
        return "index";
    }

    // 高亮显示
    @RequestMapping("/searchText2")
    @Obsolete
    public String searchText2(String text, HttpServletRequest request) throws IOException, ParseException, InvalidTokenOffsetsException {
        Directory directory = FSDirectory.open(FileSystems.getDefault().getPath(getLucenePath()));
        // 索引读取工具
        IndexReader reader = DirectoryReader.open(directory);
        // 索引搜索工具
        IndexSearcher searcher = new IndexSearcher(reader);
        String[] str = {"title", "descs"};
        // 创建查询解析器,两个参数：默认要查询的字段的名称，分词器
        MultiFieldQueryParser parser = new MultiFieldQueryParser(str, new MyIKAnalyzer());
        // 创建查询对象
        Query query = parser.parse(text);
        // 获取前十条记录
        TopDocs topDocs = searcher.search(query, 100);
        // 获取总条数
        System.out.println("本次搜索共找到" + topDocs.totalHits + "条数据");

        //高亮显示
        SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<span style='color:red'>", "</span>");
        Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
        Fragmenter fragmenter = new SimpleFragmenter(100);   //高亮后的段落范围在100字内
        highlighter.setTextFragmenter(fragmenter);

        // 获取得分文档对象（ScoreDoc）数组.SocreDoc中包含：文档的编号、文档的得分
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        List<Content> list = new ArrayList<>();
        for (ScoreDoc scoreDoc : scoreDocs) {
            // 取出文档编号
            int docID = scoreDoc.doc;
            // 根据编号去找文档
            Document doc = reader.document(docID);
            Content content = new Content();//contentMapper.selectByPrimaryKey(doc.get("id"));
            //处理高亮字段显示
            String title = highlighter.getBestFragment(new MyIKAnalyzer(), "title", doc.get("title"));
            if (title == null) {
                title = content.getTitle();
            }
            String descs = highlighter.getBestFragment(new MyIKAnalyzer(), "descs", doc.get("descs"));
            if (descs == null) {
                descs = content.getDescs();
            }
            content.setDescs(descs);
            content.setTitle(title);
            list.add(content);
        }
        request.setAttribute("list", list);
        return "index";
    }
    // endregion


    // 分页查询
    // used In Vue
    @RequestMapping(value = "/searchHighlight", method = RequestMethod.GET)
    public Result<?> searchText3(String text, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                 @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req)
            throws IOException, ParseException, InvalidTokenOffsetsException {
        Directory directory = FSDirectory.open(FileSystems.getDefault().getPath(getLucenePath()));
        // 索引读取工具
        IndexReader reader = DirectoryReader.open(directory);
        // 索引搜索工具
        IndexSearcher searcher = new IndexSearcher(reader);
        String[] str = {"JH", "SGMC", "FSRQ", "JCRQ", "DSJS", "ZJZH", "FSJGJYY", "SGCLGK", "SGDJ", "SGLB"};
        // 创建查询解析器,两个参数：默认要查询的字段的名称，分词器
        MultiFieldQueryParser parser = new MultiFieldQueryParser(str, new MyIKAnalyzer());
        // 创建查询对象
        Query query = parser.parse(text);
        // 获取前十条记录
        //TopDocs topDocs = searcher.search(query, 100);

        TopDocs topDocs = searchByPage(pageNo, pageSize, searcher, query);
        // 获取总条数
        System.out.println("本次搜索共找到" + topDocs.totalHits + "条数据");

        //高亮显示
        SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<span style='color:red'>", "</span>");
        Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
        Fragmenter fragmenter = new SimpleFragmenter(100);   //高亮后的段落范围在100字内
        highlighter.setTextFragmenter(fragmenter);

        // 获取得分文档对象（ScoreDoc）数组.SocreDoc中包含：文档的编号、文档的得分
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        List<Map<String, String>> list = new ArrayList<>();
        for (ScoreDoc scoreDoc : scoreDocs) {
            // 取出文档编号
            int docID = scoreDoc.doc;
            // 根据编号去找文档
            Document doc = reader.document(docID);
            String id = doc.get("ID");
            String jh = doc.get("JH");
            String zjzh = doc.get("ZJZH");
            String sgmc = doc.get("SGMC");
            String fsrq = doc.get("FSRQ");
            String jcrq = doc.get("JCRQ");
            String dsjs = doc.get("DSJS");
            String fsjgjyy = doc.get("FSJGJYY");
            String sgclgk = doc.get("SGCLGK");
            String sgdj = doc.get("SGDJ");
            String sglb = doc.get("SGLB");
            if (StringUtils.isNotEmpty(dsjs)) {

            }

            Map<String, String> single = new HashMap<>();

            jh = HighlightStr(jh, highlighter, "jh");
            zjzh = HighlightStr(zjzh, highlighter, "zjzh");
            sgmc = HighlightStr(sgmc, highlighter, "sgmc");
            dsjs = HighlightStr(dsjs, highlighter, "dsjs");
            fsjgjyy = HighlightStr(fsjgjyy, highlighter, "fsjgjyy");
            sgclgk = HighlightStr(sgclgk, highlighter, "sgclgk");
            sgdj = HighlightStr(sgdj, highlighter, "sgdj");
            sglb = HighlightStr(sglb, highlighter, "sglb");
            single.put("id", id);
            single.put("jh", jh);
            single.put("zjzh", zjzh);
            single.put("sgmc", sgmc);
            single.put("fsrq", fsrq);
            single.put("jcrq", jcrq);
            single.put("dsjs", dsjs);
            single.put("fsjgjyy", fsjgjyy);
            single.put("sgclgk", sgclgk);
            single.put("sgdj", sgdj);
            single.put("sglb", sglb);

            list.add(single);
        }
        System.err.println("list的长度：" + list.size());
        Result<HashMap<String, Object>> result = new Result<>();
        HashMap<String, Object> temp = new HashMap<>();
        temp.put("pageNo", pageNo);
        temp.put("pageSize", pageSize);
        temp.put("data", list);
        temp.put("total", topDocs.totalHits);
        result.setResult(temp);
        return result;
    }

    private String HighlightStr(String src, Highlighter highlighter, String fieldName) {
        if (StringUtils.isEmpty(src)) {
            return "";
        }
        try {
            String temp = src;
            temp = highlighter.getBestFragment(new MyIKAnalyzer(), fieldName, temp);
            if (StringUtils.isEmpty(temp)) {
                return src;
            } else {
                return temp;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return src;
        }
    }

    private TopDocs searchByPage(int page, int perPage, IndexSearcher searcher, Query query) throws IOException {
        TopDocs result = null;
        if (query == null) {
            System.out.println(" Query is null return null ");
            return null;/**/
        }
        ScoreDoc before = null;
        if (page != 1) {
            TopDocs docsBefore = searcher.search(query, (page - 1) * perPage);
            ScoreDoc[] scoreDocs = docsBefore.scoreDocs;
            if (scoreDocs.length > 0) {
                before = scoreDocs[scoreDocs.length - 1];
            }
        }
        result = searcher.searchAfter(before, query, perPage);
        return result;
    }


    // used In Vue
    @RequestMapping(value = "/createFzqkIndex", method = RequestMethod.GET)
    public String createFzqkIndex() throws IOException {
        // region
        String sql = "select t.jh,\n" +
                "       t.sgxh,\n" +
                "       t.sgmc,\n" +
                "       t.fsrq,\n" +
                "       t.fssj,\n" +
                "       t.jcrq,\n" +
                "       t.jcsj,\n" +
                "       t.sssj,\n" +
                "       t.dsjs,\n" +
                "       t.nyhbkzz zjzh,\n" +
                "       t.fsjgjyy,\n" +
                "       t.sgclgk,\n" +
                "       t.zjssje,\n" +
                "       t1.name sgdj ,\n" +
                "       t2.name sglb,\n" +
                "       t.ljkbs \n" +
                "  from jsra t\n" +
                "  left join text_cl t1 on t.sgdjbh = t1.id\n" +
                "  left join text_cl t2 on t.sglbid = t2.id\n" +
                " order by jh, sgxh\n";
        int pageSize = 20;
        int pageNo = 1;
        int start = pageNo * pageSize - pageSize;
        int end = pageNo * pageSize;
        String condition = "";
        String countSql = " select count(*) from (" + sql.toString() + " ）" + condition;
        // TODO: 数据量不大，一次取回，可改为分批取回
//        int count = iZjfzService.getJdbc().queryForObject(countSql, int.class);

        String pageSql = "select * from (select rownum a,t.* from (" + sql + " " + condition + ") t where rownum<=" + end + ") where a>" + start;
        List<Map<String, Object>> list = iZjfzService.querySql(sql, null);
        // endregion

        // 创建文档的集合
        Collection<Document> docs = new ArrayList<>();
        for (Map<String, Object> row : list) {
            // 创建文档对象
            Document document1 = new Document();
            //StringField会创建索引，但是不会被分词，TextField，即创建索引又会被分词。
            document1.add(new StringField("ID", TryParseStr(row.get("JH")) + "_" + TryParseStr(row.get("SGXH")), Field.Store.YES));
            document1.add(new StringField("JH", row.get("JH").toString(), Field.Store.YES));

            document1.add(new TextField("SGMC", TryParseStr(row.get("SGMC")), Field.Store.YES));
            document1.add(new TextField("FSRQ", TryParseStr(row.get("FSRQ")), Field.Store.YES));
            document1.add(new TextField("JCRQ", TryParseStr(row.get("JCRQ")), Field.Store.YES));
            document1.add(new DoubleDocValuesField("SSSJ", TryParseDouble(row.get("SSSJ"))));
            document1.add(new DoubleDocValuesField("DSJS", TryParseDouble(row.get("DSJS"))));
            document1.add(new TextField("ZJZH", TryParseStr(row.get("ZJZH")), Field.Store.YES));
            document1.add(new TextField("FSJGJYY", TryParseStr(row.get("FSJGJYY")), Field.Store.YES));
            document1.add(new TextField("SGCLGK", TryParseStr(row.get("SGCLGK")), Field.Store.YES));
            document1.add(new TextField("SGDJ", TryParseStr(row.get("SGDJ")), Field.Store.YES));
            document1.add(new TextField("SGLB", TryParseStr(row.get("SGLB")), Field.Store.YES));
            docs.add(document1);
        }

        // 索引目录类,指定索引在硬盘中的位置，我的设置为D盘的indexDir文件夹
        Directory directory = FSDirectory.open(FileSystems.getDefault().getPath(getLucenePath()));
        // 引入IK分词器
        Analyzer analyzer = new MyIKAnalyzer();
        // 索引写出工具的配置对象，这个地方就是最上面报错的问题解决方案
        IndexWriterConfig conf = new IndexWriterConfig(analyzer);
        // 设置打开方式：OpenMode.APPEND 会在索引库的基础上追加新索引。OpenMode.CREATE会先清空原来数据，再提交新的索引
        conf.setOpenMode(IndexWriterConfig.OpenMode.CREATE);
        // 创建索引的写出工具类。参数：索引的目录和配置信息
        IndexWriter indexWriter = new IndexWriter(directory, conf);
        // 把文档集合交给IndexWriter
        indexWriter.addDocuments(docs);
        // 提交
        indexWriter.commit();
        // 关闭
        indexWriter.close();
        return "success";
    }

    private double TryParseDouble(Object src) {
        if (src == null) {
            return 0;
        }
        try {
            double t = Double.parseDouble(src.toString());
            return t;
        } catch (Exception ex) {
            return 0;
        }
    }

    private String TryParseStr(Object src) {
        if (src == null) {
            return "";
        } else {
            return src.toString().trim();
        }
    }
}
