Jelajahi Sumber

更新基于 lucene 的 search-service

reghao 7 bulan lalu
induk
melakukan
116a4c066c

+ 5 - 6
search/search-service/src/main/java/cn/reghao/tnb/search/app/controller/SearchController.java → search/search-service/src/main/java/cn/reghao/tnb/search/app/controller/WenshuSearchController.java

@@ -16,10 +16,10 @@ import org.springframework.web.bind.annotation.*;
  */
 @RestController
 @RequestMapping("/api/search1/wenshu")
-public class SearchController {
+public class WenshuSearchController {
     private final WenshuSearchService wenshuSearchService;
 
-    public SearchController(WenshuSearchService wenshuSearchService) {
+    public WenshuSearchController(WenshuSearchService wenshuSearchService) {
         this.wenshuSearchService = wenshuSearchService;
     }
 
@@ -41,13 +41,12 @@ public class SearchController {
         int total = (int) page.getTotalElements();
         List<WenshuResult> list = page.getContent().stream().map(WenshuResult::new).collect(Collectors.toList());
         PageList<WenshuResult> pageList = PageList.pageList(pageNumber, pageSize, total, list);*/
-
         return WebResult.success(pageList1);
     }
 
-    @GetMapping(value = "/detail/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String getWenshuDetail(@PathVariable("id") String id) {
-        Wenshu wenshu = wenshuSearchService.queryById(id);
+    @GetMapping(value = "/detail", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getWenshuDetail(@RequestParam("id") String id, @RequestParam("keyword") String keyword) {
+        Wenshu wenshu = wenshuSearchService.queryById(id, keyword);
         return WebResult.success(wenshu);
     }
 }

+ 5 - 3
search/search-service/src/main/java/cn/reghao/tnb/search/app/es/QueryService.java

@@ -43,14 +43,15 @@ public class QueryService<T> {
         int pageSize = elasticQuery.getPageSize();
         int pageNumber = elasticQuery.getPageNumber();
         String indexName = elasticQuery.getIndexName();
-        String highlightFieldName = elasticQuery.getHighlightFieldName();
-        List<String> otherFiledNames = elasticQuery.getOtherFiledNames();
+        List<String> queryFiledNames = elasticQuery.getQueryFiledNames();
+        List<String> highlightFieldNames = elasticQuery.getHighlightFiledNames();
+
         String queryString = elasticQuery.getQueryString();
 
         // 1.构建查询的对象
         QueryStringQuery stringQuery = new QueryStringQuery.Builder()
                 // 查询的字段
-                .fields(highlightFieldName, otherFiledNames.toArray(new String[0]))
+                .fields(queryFiledNames)
                 .query(queryString)
                 .build();
         Query query = new Query.Builder()
@@ -63,6 +64,7 @@ public class QueryService<T> {
                         .must(m -> m.queryString(stringQuery))))
                 .build();
 
+        String highlightFieldName = highlightFieldNames.get(0);
         // 2.高亮显示
         HighlightField highlightField = new HighlightField.Builder()
                 .matchedFields(highlightFieldName)

+ 6 - 0
search/search-service/src/main/java/cn/reghao/tnb/search/app/lucene/LuceneDocument.java

@@ -52,8 +52,14 @@ public class LuceneDocument {
         Document doc = new Document();
         doc.add(new StringField("id", videoText.getId(), org.apache.lucene.document.Field.Store.YES));
         doc.add(new TextField("title", videoText.getTitle(), org.apache.lucene.document.Field.Store.YES));
+        doc.add(new TextField("description", videoText.getDescription(), org.apache.lucene.document.Field.Store.YES));
         // 对 int 型字段索引(只索引不存储)
         doc.add(new IntPoint("scope", videoText.getScope()));
+        doc.add(new StoredField("scope", videoText.getScope()));
+        // 对 long 型字段索引(只索引不存储)
+        doc.add(new LongPoint("publishTime", videoText.getPublishTime()));
+        // 使用 StoredField 存储 long 型字段, StoredField 只会存储, 不会分词, 也不会索引
+        doc.add(new StoredField("publishTime", videoText.getPublishTime()));
         return doc;
     }
 

+ 52 - 8
search/search-service/src/main/java/cn/reghao/tnb/search/app/lucene/LuceneIndex.java

@@ -1,5 +1,6 @@
 package cn.reghao.tnb.search.app.lucene;
 
+import cn.reghao.tnb.search.app.config.ElasticProperties;
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.index.*;
@@ -12,6 +13,7 @@ import org.wltea.analyzer.lucene.IKAnalyzer;
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Paths;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -20,11 +22,11 @@ import java.util.List;
  */
 @Service
 public class LuceneIndex {
-    private String nativeLuceneDir = "/opt/data/search_data/native_lucene";
-    private String hibernateLuceneDir = "/opt/data/search_data/hibernate_lucene";
+    private final String nativeLuceneDir;
     private final Analyzer luceneAnalyzer;
 
-    public LuceneIndex() {
+    public LuceneIndex(ElasticProperties elasticProperties) {
+        this.nativeLuceneDir = elasticProperties.getNativeLuceneDir();
         this.luceneAnalyzer = new IKAnalyzer();
     }
 
@@ -32,7 +34,7 @@ public class LuceneIndex {
         String indexDir = String.format("%s/%s", nativeLuceneDir, indexName);
         File dir = new File(indexDir);
         Directory indexDirectory = FSDirectory.open(dir.toPath());
-        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(luceneAnalyzer);
+        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(this.luceneAnalyzer);
         return new IndexWriter(indexDirectory, indexWriterConfig);
     }
 
@@ -42,6 +44,10 @@ public class LuceneIndex {
         return DirectoryReader.open(directory);
     }
 
+    private IndexReader getIndexReader(IndexWriter indexWriter) throws IOException {
+        return DirectoryReader.open(indexWriter);
+    }
+
     public void createIndex(String indexName, Document document) throws IOException {
         IndexWriter indexWriter = getIndexWriter(indexName);
         indexWriter.addDocument(document);
@@ -74,18 +80,53 @@ public class LuceneIndex {
     }
 
     public void addOrUpdateIndex(String indexName, Document document) throws IOException {
-        IndexReader indexReader = getIndexReader(indexName);
+        IndexWriter indexWriter = getIndexWriter(indexName);
+        IndexReader indexReader = getIndexReader(indexWriter);
         IndexSearcher indexSearcher = new IndexSearcher(indexReader);
 
         String id = document.get("id");
         Query query = new TermQuery(new Term("id", id));
         TopDocs topDocs = indexSearcher.search(query, 1);
         ScoreDoc[] scoreDocs = topDocs.scoreDocs;
+
         if (scoreDocs.length == 1) {
-            updateIndex(indexName, document);
+            String fieldName = "id";
+            String fieldValue = document.get("id");
+            indexWriter.updateDocument(new Term(fieldName, fieldValue), document);
         } else {
-            createIndex(indexName, document);
+            indexWriter.addDocument(document);
+        }
+        indexWriter.commit();
+        indexWriter.close();
+    }
+
+    public void batchAddOrUpdateIndex(String indexName, List<Document> documents) throws IOException {
+        IndexWriter indexWriter = getIndexWriter(indexName);
+        IndexReader indexReader = getIndexReader(indexWriter);
+        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
+
+        List<String> failedList = new ArrayList<>();
+        for (Document document : documents) {
+            String id = document.get("id");
+            try {
+                Query query = new TermQuery(new Term("id", id));
+                TopDocs topDocs = indexSearcher.search(query, 1);
+                ScoreDoc[] scoreDocs = topDocs.scoreDocs;
+                if (scoreDocs.length == 1) {
+                    String fieldName = "id";
+                    String fieldValue = document.get("id");
+                    indexWriter.updateDocument(new Term(fieldName, fieldValue), document);
+                } else {
+                    indexWriter.addDocument(document);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+                failedList.add(id);
+            }
         }
+        indexWriter.commit();
+        indexWriter.close();
+        failedList.size();
     }
 
     public void deleteIndex(String indexName, String id) throws IOException {
@@ -103,7 +144,8 @@ public class LuceneIndex {
     }
 
     public void check(String indexName) throws IOException {
-        IndexReader indexReader = getIndexReader(indexName);
+        IndexWriter indexWriter = getIndexWriter(indexName);
+        IndexReader indexReader = getIndexReader(indexWriter);
 
         // 总共的索引文档
         int maxDocs = indexReader.maxDoc();
@@ -111,6 +153,7 @@ public class LuceneIndex {
         int numDocs = indexReader.numDocs();
         // 被标记删除的索引文档
         int numDeletedDocs = indexReader.numDeletedDocs();
+        indexWriter.close();
     }
 
     public void restore() {
@@ -126,5 +169,6 @@ public class LuceneIndex {
     public void forceDelete(String indexName) throws IOException {
         IndexWriter indexWriter = getIndexWriter(indexName);
         indexWriter.forceMergeDeletes();
+        indexWriter.close();
     }
 }

+ 58 - 6
search/search-service/src/main/java/cn/reghao/tnb/search/app/lucene/LuceneQuery.java → search/search-service/src/main/java/cn/reghao/tnb/search/app/lucene/LuceneQueryBuilder.java

@@ -1,7 +1,8 @@
 package cn.reghao.tnb.search.app.lucene;
 
-import lombok.extern.slf4j.Slf4j;
+import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.document.Document;
+import org.apache.lucene.document.IntPoint;
 import org.apache.lucene.document.LongPoint;
 import org.apache.lucene.index.DirectoryReader;
 import org.apache.lucene.index.IndexReader;
@@ -16,13 +17,65 @@ import org.wltea.analyzer.lucene.IKAnalyzer;
 
 import java.io.IOException;
 import java.nio.file.Paths;
+import java.util.Set;
 
 /**
  * @author reghao
  * @date 2025-08-20 17:32:59
  */
-@Slf4j
-public class LuceneQuery {
+public class LuceneQueryBuilder {
+    public void search() throws Exception {
+        Analyzer luceneAnalyzer = new IKAnalyzer();
+        String keyword = "";
+
+        String field = "title";
+        QueryParser queryParser = new QueryParser(field, luceneAnalyzer);
+        Query query = queryParser.parse(keyword);
+
+        Query termQuery = new TermQuery(new Term(field, keyword));
+
+        Query fuzzyQuery = new FuzzyQuery(new Term(field, keyword), 1);
+
+        PhraseQuery.Builder builder = new PhraseQuery.Builder();
+        builder.add(new Term(field, keyword), 1);
+        Query phraseQuery = builder.build();
+
+        Set<Integer> scopes = Set.of();
+        Query titleQuery = new QueryParser("title", luceneAnalyzer).parse(keyword);
+        // 数值集合
+        Query setQuery = IntPoint.newSetQuery("scope", scopes);
+        // 布尔运算, MUST + MUST 表示查找 2 个都有的部分
+        Query booleanQuery = new BooleanQuery.Builder()
+                .add(titleQuery, BooleanClause.Occur.MUST)
+                .add(setQuery, BooleanClause.Occur.MUST)
+                .build();
+
+        // 字符串精确查询(等值查询)
+        Query termQuery1 = new TermQuery(new Term("scope", "1"));
+        Term term1 = new Term("scope", "1");
+        Term term2 = new Term("scope", "2");
+
+        // 数值精确查询
+        Query exactQuery1 = IntPoint.newExactQuery("scope", 1);
+        // 数值集合
+        // Query setQuery = IntPoint.newSetQuery("scope", 1, 2, 3);
+
+        // 数值范围查询
+        // PointRangeQuery
+        IntPoint.newRangeQuery("", 1, 4);
+
+        // 排序
+        SortField sortField = new SortField("publishTime", SortField.Type.LONG,false);
+        Sort sort = new Sort(sortField);
+        int pageSize = 10;
+
+        String indexDir = "";
+        Directory directory = FSDirectory.open(Paths.get(indexDir));
+        IndexReader indexReader = DirectoryReader.open(directory);
+        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
+        indexSearcher.search(booleanQuery, pageSize, sort);
+    }
+
     static void termQuery() {
         Query query = new TermQuery(new Term("name", "李白"));
         query(query);
@@ -108,12 +161,11 @@ public class LuceneQuery {
 
             // 查询前 100 条数据
             TopDocs topDocs = indexSearcher.search(query, 100);
-            log.info("本次搜索共找到" + topDocs.totalHits.value + "条数据");
+            System.out.printf("本次搜索共找到 %s 条数据\n", topDocs.totalHits.value);
             ScoreDoc[] scoreDocs = topDocs.scoreDocs;
             for (ScoreDoc scoreDoc : scoreDocs) {
                 Document document = indexReader.document(scoreDoc.doc);
-                log.info(document.toString());
-                //log.info("id={},name={},poems={},success={},score={}", document.get("id"), document.get("name"), document.get("poems"), document.get("success"), scoreDoc.score);
+                System.out.println(document.toString());
             }
         } catch (IOException e) {
             e.printStackTrace();

+ 142 - 146
search/search-service/src/main/java/cn/reghao/tnb/search/app/lucene/LuceneSearch.java

@@ -1,11 +1,16 @@
 package cn.reghao.tnb.search.app.lucene;
 
+import cn.reghao.jutil.jdk.db.Page;
 import cn.reghao.jutil.jdk.db.PageList;
+import cn.reghao.tnb.search.app.config.ElasticProperties;
 import cn.reghao.tnb.search.app.model.vo.ElasticQuery;
+import cn.reghao.tnb.search.app.model.vo.LuceneQuery;
 import cn.reghao.tnb.search.app.model.vo.SearchResult;
+import cn.reghao.tnb.search.app.model.vo.VideoQuery;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.document.Document;
+import org.apache.lucene.document.IntPoint;
 import org.apache.lucene.index.DirectoryReader;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.Term;
@@ -33,120 +38,41 @@ import java.util.stream.Collectors;
 @Slf4j
 @Service
 public class LuceneSearch {
-    private String nativeLuceneDir = "/opt/data/search_data/native_lucene";
+    private String nativeLuceneDir;
     private Analyzer luceneAnalyzer;
     private SimpleHTMLFormatter formatter;
+    private Map<String, IndexReader> indexReaderMap = new HashMap<>();
 
-    public LuceneSearch() {
+    public LuceneSearch(ElasticProperties elasticProperties) {
+        this.nativeLuceneDir = elasticProperties.getNativeLuceneDir();
         this.luceneAnalyzer = new IKAnalyzer();
         this.formatter = new SimpleHTMLFormatter("<span style='color:red;'>", "</span>");
     }
 
-    public IndexSearcher getIndexSearcher(String indexName) throws IOException {
-        String indexDir = String.format("%s/%s", nativeLuceneDir, indexName);
-        Directory directory = FSDirectory.open(Paths.get(indexDir));
-        IndexReader indexReader = DirectoryReader.open(directory);
-        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
-        return indexSearcher;
+    // TODO 并发处理
+    public IndexReader getIndexReader(String indexName) throws IOException {
+        IndexReader indexReader = indexReaderMap.get(indexName);
+        if (indexReader == null) {
+            synchronized (this) {
+                indexReader = getIndexReader0(indexName);
+                indexReaderMap.put(indexName, indexReader);
+            }
+        }
+
+        return indexReader;
     }
 
-    public IndexReader getIndexReader(String indexName) throws IOException {
+    public IndexReader getIndexReader0(String indexName) throws IOException {
         String indexDir = String.format("%s/%s", nativeLuceneDir, indexName);
         Directory directory = FSDirectory.open(Paths.get(indexDir));
-        return DirectoryReader.open(directory);
+        IndexReader indexReader = DirectoryReader.open(directory);
+        return indexReader;
     }
 
     public PageList queryWithHighlight(ElasticQuery elasticQuery, Class clazz) {
-        int pageSize = elasticQuery.getPageSize();
-        int pageNumber = elasticQuery.getPageNumber();
-        String indexName = elasticQuery.getIndexName();
-        String highlightFieldName = elasticQuery.getHighlightFieldName();
-        List<String> otherFiledNames = elasticQuery.getOtherFiledNames();
-        String queryString = elasticQuery.getQueryString();
         try {
-            Set<String> queryFields = new HashSet<>(otherFiledNames);
-            queryFields.add(highlightFieldName);
-
-            Query query;
-            if (otherFiledNames.isEmpty()) {
-                // 单字段查询
-                QueryParser queryParser = new QueryParser(highlightFieldName, luceneAnalyzer);
-                query = queryParser.parse(queryString);
-            } else {
-                // 多字段查询
-                List<String> fieldList = new ArrayList<>(otherFiledNames);
-                fieldList.add(highlightFieldName);
-                String[] fields = fieldList.toArray(new String[0]);
-                MultiFieldQueryParser multiFieldQuery = new MultiFieldQueryParser(fields, luceneAnalyzer);
-                query = multiFieldQuery.parse(queryString);
-            }
-
-            IndexReader indexReader = getIndexReader(indexName);
-            IndexSearcher indexSearcher = new IndexSearcher(indexReader);
-            long total;
-            TopDocs topDocs;
-            if (pageNumber == 1) {
-                int count = pageSize;
-                topDocs = indexSearcher.search(query, count);
-                total = topDocs.totalHits.value;
-            } else {
-                int count = (pageNumber-1)*pageSize;
-                TopDocs prevTopDocs = indexSearcher.searchAfter(null, query, count);
-                total = prevTopDocs.totalHits.value;
-
-                ScoreDoc[] prevScoreDocs = prevTopDocs.scoreDocs;
-                ScoreDoc after = prevScoreDocs[prevScoreDocs.length-1];
-                topDocs = indexSearcher.searchAfter(after, query, pageSize);
-            }
-
-            QueryScorer queryScorer = new QueryScorer(query);
-            Highlighter highlighter = new Highlighter(formatter, queryScorer);
-
-            Map<String, Field> map = Arrays.stream(clazz.getDeclaredFields())
-                    .collect(Collectors.toMap(Field::getName, k -> k));
-            //List<T> list = new ArrayList<>();
-            List<Object> list = new ArrayList<>();
-            ScoreDoc[] scoreDocs = topDocs.scoreDocs;
-            for (ScoreDoc scoreDoc : scoreDocs) {
-                Document document = indexReader.document(scoreDoc.doc);
-
-                //T tObject = null;
-                Object object = null;
-                for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
-                    int len = constructor.getParameterTypes().length;
-                    if (len == 0) {
-                        object = constructor.newInstance();
-                    }
-                }
-
-                for (Map.Entry<String, Field> entry : map.entrySet()) {
-                    String fieldName = entry.getKey();
-                    Field field0 = clazz.getDeclaredField(fieldName);
-
-                    String fieldValue = document.get(fieldName);
-                    /*if (fieldName.equals(highlightFieldName)) {
-                        fieldValue = highlighter.getBestFragment(luceneAnalyzer, highlightFieldName, fieldValue);
-                    }*/
-                    if (queryFields.contains(fieldName)) {
-                        fieldValue = highlighter.getBestFragment(luceneAnalyzer, fieldName, fieldValue);
-                    }
-
-                    field0.setAccessible(true);
-                    Class<?> fieldType = field0.getType();
-                    if (fieldType.equals(String.class)) {
-                        field0.set(object, fieldValue);
-                    } else if (field0.getType().equals(int.class) || field0.getType().equals(Integer.class)) {
-                        field0.set(object, Integer.parseInt(fieldValue));
-                    } else if (field0.getType().equals(long.class) || field0.getType().equals(Long.class)) {
-                        field0.set(object, Long.parseLong(fieldValue));
-                    } else if (field0.getType().equals(double.class) || field0.getType().equals(Double.class)) {
-                        field0.set(object, Double.parseDouble(fieldValue));
-                    }
-                }
-                list.add(object);
-            }
-
-            return PageList.pageList(pageNumber, pageSize, (int) total, list);
+            LuceneQuery luceneQuery = getLuceneQueryByElasticQuery(elasticQuery);
+            return getResults(luceneQuery, clazz);
         } catch (Exception e) {
             e.printStackTrace();
         }
@@ -154,19 +80,60 @@ public class LuceneSearch {
         return PageList.empty();
     }
 
-    public SearchResult search(String indexName, String keyword, int pageNumber, int pageSize) throws Exception {
-        String field = "fullText";
-        QueryParser queryParser = new QueryParser(field, luceneAnalyzer);
-        Query query = queryParser.parse(keyword);
-        Query query1 = new TermQuery(new Term(field, keyword));
+    private LuceneQuery getLuceneQueryByElasticQuery(ElasticQuery elasticQuery) throws Exception {
+        int pageSize = elasticQuery.getPageSize();
+        int pageNumber = elasticQuery.getPageNumber();
+        String indexName = elasticQuery.getIndexName();
+        List<String>  queryFiledNames = elasticQuery.getQueryFiledNames();
+        Set<String> highlightFiledNames = new HashSet<>(elasticQuery.getHighlightFiledNames());
+        String queryString = elasticQuery.getQueryString();
+        Query query = getQueryByQueryParser(queryFiledNames, queryString);
+        return new LuceneQuery.Builder()
+                .pageSize(pageSize)
+                .pageNumber(pageNumber)
+                .indexName(indexName)
+                .highlightFiledNames(highlightFiledNames)
+                .query(query)
+                .build();
+    }
+
+    private LuceneQuery getLuceneQueryByVideoQuery(VideoQuery videoQuery) throws Exception {
+        int pageSize = videoQuery.getPageSize();
+        List<String>  queryFiledNames = videoQuery.getQueryFiledNames();
+        Set<String> highlightFiledNames = new HashSet<>(videoQuery.getHighlightFiledNames());
+        int pageNumber = videoQuery.getPageNumber();
+        String indexName = videoQuery.getIndexName();
+
+        Query query1 = getQueryByQueryParser(queryFiledNames, videoQuery.getQueryString());
+        Query query2 = IntPoint.newSetQuery("scope", videoQuery.getScopes());
+        Query query = new BooleanQuery.Builder()
+                .add(query1, BooleanClause.Occur.MUST)
+                .add(query2, BooleanClause.Occur.MUST)
+                .build();
+
+        return new LuceneQuery.Builder()
+                .pageSize(pageSize)
+                .pageNumber(pageNumber)
+                .indexName(indexName)
+                .highlightFiledNames(highlightFiledNames)
+                .query(query)
+                .build();
+    }
+
+    private PageList getResults(LuceneQuery luceneQuery, Class clazz) throws Exception {
+        String indexName = luceneQuery.getIndexName();
+        int pageNumber = luceneQuery.getPageNumber();
+        int pageSize = luceneQuery.getPageSize();
+        Query query = luceneQuery.getQuery();
+        Set<String> highlightFiledNames = luceneQuery.getHighlightFiledNames();
 
         IndexReader indexReader = getIndexReader(indexName);
         IndexSearcher indexSearcher = new IndexSearcher(indexReader);
         long total;
         TopDocs topDocs;
         if (pageNumber == 1) {
-            // topDocs = indexSearcher.search(query, pageSize);
-            topDocs = indexSearcher.searchAfter(null, query, pageSize);
+            int count = pageSize;
+            topDocs = indexSearcher.search(query, count);
             total = topDocs.totalHits.value;
         } else {
             int count = (pageNumber-1)*pageSize;
@@ -181,59 +148,86 @@ public class LuceneSearch {
         QueryScorer queryScorer = new QueryScorer(query);
         Highlighter highlighter = new Highlighter(formatter, queryScorer);
 
+        Map<String, Field> map = Arrays.stream(clazz.getDeclaredFields())
+                .collect(Collectors.toMap(Field::getName, k -> k));
+        //List<T> list = new ArrayList<>();
+        List<Object> list = new ArrayList<>();
         ScoreDoc[] scoreDocs = topDocs.scoreDocs;
-        Map<String, String> map = new HashMap<>();
         for (ScoreDoc scoreDoc : scoreDocs) {
             Document document = indexReader.document(scoreDoc.doc);
-            String id = document.get("id");
-            String caseName = document.get("caseName");
-            String fullText = document.get("fullText");
-            String caseNameHighlight = highlighter.getBestFragment(luceneAnalyzer, field, fullText);
+
+            //T tObject = null;
+            Object object = null;
+            for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
+                int len = constructor.getParameterTypes().length;
+                if (len == 0) {
+                    object = constructor.newInstance();
+                }
+            }
+
+            for (Map.Entry<String, Field> entry : map.entrySet()) {
+                String fieldName = entry.getKey();
+                Field field0 = clazz.getDeclaredField(fieldName);
+
+                String fieldValue = document.get(fieldName);
+                if (highlightFiledNames.contains(fieldName)) {
+                    fieldValue = highlighter.getBestFragment(luceneAnalyzer, fieldName, fieldValue);
+                }
+
+                field0.setAccessible(true);
+                Class<?> fieldType = field0.getType();
+                if (fieldType.equals(String.class)) {
+                    field0.set(object, fieldValue);
+                } else if (field0.getType().equals(int.class) || field0.getType().equals(Integer.class)) {
+                    field0.set(object, Integer.parseInt(fieldValue));
+                } else if (field0.getType().equals(long.class) || field0.getType().equals(Long.class)) {
+                    field0.set(object, Long.parseLong(fieldValue));
+                } else if (field0.getType().equals(double.class) || field0.getType().equals(Double.class)) {
+                    field0.set(object, Double.parseDouble(fieldValue));
+                }
+            }
+            list.add(object);
         }
 
-        return new SearchResult(total, map);
+        return PageList.pageList(pageNumber, pageSize, (int) total, list);
     }
 
-    public SearchResult highlighter(String indexName, String keyword, int pageSize, int pageNumber)
-            throws IOException, InvalidTokenOffsetsException, ParseException {
-        String field = "title";
-        QueryParser queryParser = new QueryParser(field, luceneAnalyzer);
-        Query query = queryParser.parse(keyword);
-        TermQuery termQuery = new TermQuery(new Term(field, keyword));
-        FuzzyQuery fuzzyQuery = new FuzzyQuery(new Term(field, keyword), 1);
-        PhraseQuery.Builder builder = new PhraseQuery.Builder();
-        builder.add(new Term(field, keyword), 1);
-        PhraseQuery phraseQuery = builder.build();
+    public PageList queryWithHighlight(VideoQuery videoQuery, Class clazz) {
+        try {
+            LuceneQuery luceneQuery = getLuceneQueryByVideoQuery(videoQuery);
+            return getResults(luceneQuery, clazz);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
 
-        IndexReader indexReader = getIndexReader(indexName);
-        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
-        long total;
-        TopDocs topDocs;
-        if (pageNumber == 1) {
-            topDocs = indexSearcher.search(termQuery, pageSize);
-            total = topDocs.totalHits.value;
-        } else {
-            int count = (pageNumber-1)*pageSize;
-            TopDocs prevTopDocs = indexSearcher.searchAfter(null, query, count);
-            total = prevTopDocs.totalHits.value;
+        return PageList.empty();
+    }
 
-            ScoreDoc[] prevScoreDocs = prevTopDocs.scoreDocs;
-            ScoreDoc after = prevScoreDocs[prevScoreDocs.length-1];
-            topDocs = indexSearcher.searchAfter(after, query, pageSize);
+    private Query getQueryByQueryParser(List<String> queryFiledNames, String queryString) throws Exception {
+        Query query;
+        if (queryFiledNames.size() == 1) {
+            // 单字段查询
+            QueryParser queryParser = new QueryParser(queryFiledNames.get(0), luceneAnalyzer);
+            query = queryParser.parse(queryString);
+        } else if (queryFiledNames.size() > 1) {
+            // 多字段查询
+            String[] fields = queryFiledNames.toArray(new String[0]);
+            MultiFieldQueryParser multiFieldQuery = new MultiFieldQueryParser(fields, luceneAnalyzer);
+            query = multiFieldQuery.parse(queryString);
+        } else {
+            throw new Exception("query field is empty");
         }
 
-        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
-        Map<String, String> map = new HashMap<>();
+        return query;
+    }
+
+    public String getHighlightText(String fieldName, String fieldValue, String queryString) throws Exception {
+        List<String> queryFiledNames = List.of(fieldName);
+        Query query = getQueryByQueryParser(queryFiledNames, queryString);
+
         QueryScorer queryScorer = new QueryScorer(query);
         Highlighter highlighter = new Highlighter(formatter, queryScorer);
-        for (ScoreDoc scoreDoc : scoreDocs) {
-            Document document = indexReader.document(scoreDoc.doc);
-            String videoId = document.get("videoId");
-            String title = document.get("title");
-            String htmlTitle = highlighter.getBestFragment(luceneAnalyzer, field, title);
-            map.put(videoId, htmlTitle);
-        }
-        return new SearchResult(total, map);
+        return highlighter.getBestFragment(luceneAnalyzer, fieldName, fieldValue);
     }
 
     public Document findDocumentById(String indexName, String id) {
@@ -246,6 +240,8 @@ public class LuceneSearch {
             ScoreDoc[] scoreDocs = topDocs.scoreDocs;
             if (scoreDocs.length == 1) {
                 Document document = indexReader.document(scoreDocs[0].doc);
+                //highlighter.getBestFragment(luceneAnalyzer, fieldName, fieldValue);
+
                 return document;
             }
         } catch (Exception e) {

+ 8 - 11
search/search-service/src/main/java/cn/reghao/tnb/search/app/model/vo/ElasticQuery.java

@@ -17,22 +17,19 @@ public class ElasticQuery {
     private String indexName;
     private List<String> queryFiledNames;
     private List<String> highlightFiledNames;
-    private String highlightFieldName;
-    private List<String> otherFiledNames;
     private String queryString;
 
     public ElasticQuery() {
         this.pageSize = 10;
         this.pageNumber = 1;
-        this.otherFiledNames = List.of();
     }
 
     private ElasticQuery(Builder builder) {
         this.pageSize = builder.pageSize;
         this.pageNumber = builder.pageNumber;
         this.indexName = builder.indexName;
-        this.highlightFieldName = builder.highlightFieldName;
-        this.otherFiledNames = builder.otherFiledNames;
+        this.queryFiledNames = builder.queryFiledNames;
+        this.highlightFiledNames = builder.highlightFiledNames;
         this.queryString = builder.queryString;
     }
 
@@ -40,8 +37,8 @@ public class ElasticQuery {
         private int pageSize;
         private int pageNumber;
         private String indexName;
-        private String highlightFieldName;
-        private List<String> otherFiledNames;
+        private List<String> queryFiledNames;
+        private List<String> highlightFiledNames;
         private String queryString;
 
         public Builder pageSize(int pageSize) {
@@ -59,13 +56,13 @@ public class ElasticQuery {
             return this;
         }
 
-        public Builder highlightFieldName(String highlightFieldName) {
-            this.highlightFieldName = highlightFieldName;
+        public Builder queryFiledNames(List<String> queryFiledNames) {
+            this.queryFiledNames = queryFiledNames;
             return this;
         }
 
-        public Builder otherFiledNames(List<String> otherFiledNames) {
-            this.otherFiledNames = otherFiledNames;
+        public Builder highlightFiledNames(List<String> highlightFiledNames) {
+            this.highlightFiledNames = highlightFiledNames;
             return this;
         }
 

+ 72 - 0
search/search-service/src/main/java/cn/reghao/tnb/search/app/model/vo/LuceneQuery.java

@@ -0,0 +1,72 @@
+package cn.reghao.tnb.search.app.model.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.lucene.search.Query;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author reghao
+ * @date 2025-08-22 15:14:50
+ */
+@Getter
+@Setter
+public class LuceneQuery {
+    private int pageSize;
+    private int pageNumber;
+    private String indexName;
+    private Set<String> highlightFiledNames;
+    private Query query;
+
+    public LuceneQuery() {
+        this.pageSize = 10;
+        this.pageNumber = 1;
+    }
+
+    private LuceneQuery(Builder builder) {
+        this.pageSize = builder.pageSize;
+        this.pageNumber = builder.pageNumber;
+        this.indexName = builder.indexName;
+        this.highlightFiledNames = builder.highlightFiledNames;
+        this.query = builder.query;
+    }
+
+    public static final class Builder {
+        private int pageSize;
+        private int pageNumber;
+        private String indexName;
+        private Set<String> highlightFiledNames;
+        private Query query;
+
+        public Builder pageSize(int pageSize) {
+            this.pageSize = pageSize;
+            return this;
+        }
+
+        public Builder pageNumber(int pageNumber) {
+            this.pageNumber = pageNumber;
+            return this;
+        }
+
+        public Builder indexName(String indexName) {
+            this.indexName = indexName;
+            return this;
+        }
+
+        public Builder highlightFiledNames(Set<String> highlightFiledNames) {
+            this.highlightFiledNames = highlightFiledNames;
+            return this;
+        }
+
+        public Builder query(Query query) {
+            this.query = query;
+            return this;
+        }
+
+        public LuceneQuery build() {
+            return new LuceneQuery(this);
+        }
+    }
+}

+ 0 - 42
search/search-service/src/main/java/cn/reghao/tnb/search/app/model/vo/VideoCard.java

@@ -1,42 +0,0 @@
-package cn.reghao.tnb.search.app.model.vo;
-
-import cn.reghao.tnb.content.api.dto.VideoPostCard;
-import cn.reghao.tnb.user.api.dto.UserCard;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.io.Serializable;
-
-/**
- * @author reghao
- * @date 2023-04-24 03:07:22
- */
-@Setter
-@Getter
-public class VideoCard implements Serializable {
-    private static final long serialVersionUID = 1L;
-
-    private String videoId;
-    private String title;
-    private String coverUrl;
-    private String duration;
-    private boolean horizontal;
-    private boolean cached;
-    private String pubDateStr;
-    private UserCard user;
-    private int view;
-    private int comment;
-
-    public VideoCard(VideoPostCard videoPostCard, String durationStr, boolean cached, String pubDateStr, UserCard user) {
-        this.videoId = videoPostCard.getVideoId();
-        this.title = videoPostCard.getTitle();
-        this.coverUrl = videoPostCard.getCoverUrl();
-        this.duration = durationStr;
-        this.horizontal = videoPostCard.isHorizontal();
-        this.cached = cached;
-        this.pubDateStr = pubDateStr;
-        this.user = user;
-        this.view = videoPostCard.getView();
-        this.comment = videoPostCard.getComment();
-    }
-}

+ 0 - 19
search/search-service/src/main/java/cn/reghao/tnb/search/app/model/vo/VideoProjection.java

@@ -1,19 +0,0 @@
-package cn.reghao.tnb.search.app.model.vo;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-
-import java.util.List;
-
-/**
- * @author reghao
- * @date 2025-04-02 09:39:36
- */
-@AllArgsConstructor
-@NoArgsConstructor
-@Getter
-public class VideoProjection {
-    private String videoId;
-    private List<String> highlightTitle;
-}

+ 86 - 0
search/search-service/src/main/java/cn/reghao/tnb/search/app/model/vo/VideoQuery.java

@@ -0,0 +1,86 @@
+package cn.reghao.tnb.search.app.model.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2025-08-22 15:06:35
+ */
+@Getter
+@Setter
+public class VideoQuery {
+    private int pageSize;
+    private int pageNumber;
+    private String indexName;
+    private List<String> queryFiledNames;
+    private List<String> highlightFiledNames;
+    private String queryString;
+    private List<Integer> scopes;
+
+    public VideoQuery() {
+        this.pageSize = 10;
+        this.pageNumber = 1;
+    }
+
+    private VideoQuery(Builder builder) {
+        this.pageSize = builder.pageSize;
+        this.pageNumber = builder.pageNumber;
+        this.indexName = builder.indexName;
+        this.queryFiledNames = builder.queryFiledNames;
+        this.highlightFiledNames = builder.highlightFiledNames;
+        this.queryString = builder.queryString;
+        this.scopes = builder.scopes;
+    }
+
+    public static final class Builder {
+        private int pageSize;
+        private int pageNumber;
+        private String indexName;
+        private List<String> queryFiledNames;
+        private List<String> highlightFiledNames;
+        private String queryString;
+        private List<Integer> scopes;
+
+        public Builder pageSize(int pageSize) {
+            this.pageSize = pageSize;
+            return this;
+        }
+
+        public Builder pageNumber(int pageNumber) {
+            this.pageNumber = pageNumber;
+            return this;
+        }
+
+        public Builder indexName(String indexName) {
+            this.indexName = indexName;
+            return this;
+        }
+
+        public Builder queryFiledNames(List<String> queryFiledNames) {
+            this.queryFiledNames = queryFiledNames;
+            return this;
+        }
+
+        public Builder highlightFiledNames(List<String> highlightFiledNames) {
+            this.highlightFiledNames = highlightFiledNames;
+            return this;
+        }
+
+        public Builder queryString(String queryString) {
+            this.queryString = queryString;
+            return this;
+        }
+
+        public Builder scopes(List<Integer> scopes) {
+            this.scopes = scopes;
+            return this;
+        }
+
+        public VideoQuery build() {
+            return new VideoQuery(this);
+        }
+    }
+}

+ 84 - 44
search/search-service/src/main/java/cn/reghao/tnb/search/app/rpc/DataSearchServiceImpl.java

@@ -5,22 +5,20 @@ import cn.reghao.tnb.search.api.iface.DataSearchService;
 import cn.reghao.tnb.search.app.es.ElasticService;
 import cn.reghao.tnb.search.app.es.VideoTextDocument;
 import cn.reghao.tnb.search.app.es.VideoTextQuery;
+import cn.reghao.tnb.search.app.lucene.LuceneDocument;
 import cn.reghao.tnb.search.app.lucene.LuceneIndex;
 import cn.reghao.tnb.search.app.lucene.LuceneSearch;
 import cn.reghao.tnb.search.app.model.po.VideoText;
 import cn.reghao.jutil.jdk.db.PageList;
+import cn.reghao.tnb.search.app.model.vo.VideoQuery;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboService;
+import org.apache.lucene.document.Document;
 import org.springframework.data.domain.Page;
 import org.springframework.stereotype.Service;
-import org.wltea.analyzer.core.IKSegmenter;
-import org.wltea.analyzer.core.Lexeme;
 
 import java.io.IOException;
-import java.io.StringReader;
-import java.util.ArrayList;
 import java.util.List;
-import java.util.Locale;
 import java.util.stream.Collectors;
 
 /**
@@ -31,77 +29,119 @@ import java.util.stream.Collectors;
 @DubboService
 @Service
 public class DataSearchServiceImpl implements DataSearchService {
-    private final String indexName = VideoText.class.getSimpleName().toLowerCase(Locale.ROOT);
+    private String indexName = "video_text";
     private int pageSize = 12;
     private final VideoTextDocument videoTextDocument;
+    private LuceneDocument luceneDocument;
     private final LuceneIndex luceneIndex;
+    private LuceneSearch luceneSearch;
     private final VideoTextQuery videoTextQuery;
+    private boolean luceneEnabled = true;
 
-    public DataSearchServiceImpl(ElasticService elasticService, LuceneSearch luceneSearch,
-                                 LuceneIndex luceneIndex, VideoTextQuery videoTextQuery) {
+    public DataSearchServiceImpl(ElasticService elasticService, VideoTextQuery videoTextQuery,
+                                 LuceneDocument luceneDocument, LuceneIndex luceneIndex, LuceneSearch luceneSearch) {
         this.videoTextDocument = new VideoTextDocument(elasticService);
-        this.luceneIndex = luceneIndex;
         this.videoTextQuery = videoTextQuery;
+        this.luceneDocument = luceneDocument;
+        this.luceneIndex = luceneIndex;
+        this.luceneSearch = luceneSearch;
     }
 
+    @Override
     public void addVideoSummary(VideoSummary videoSummary) {
         VideoText videoText = new VideoText(videoSummary);
-        videoTextDocument.addOrUpdateVideoText(videoText);
-        //luceneIndex.createVideoTextIndex(videoText);
+        if (luceneEnabled) {
+            Document document = luceneDocument.getDocumentByVideoText(videoText);
+            try {
+                luceneIndex.addOrUpdateIndex(indexName, document);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        } else {
+            videoTextDocument.addOrUpdateVideoText(videoText);
+        }
     }
 
+    @Override
     public void addVideoSummaryList(List<VideoSummary> list) {
         List<VideoText> videoTextList = list.stream()
                 .map(VideoText::new)
                 .collect(Collectors.toList());
-        videoTextDocument.batchAddVideoText(videoTextList);
+        if (luceneEnabled) {
+            List<Document> documents = videoTextList.stream()
+                    .map(videoText -> luceneDocument.getDocumentByVideoText(videoText))
+                    .collect(Collectors.toList());
+            try {
+                luceneIndex.batchAddOrUpdateIndex(indexName, documents);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        } else {
+            videoTextDocument.batchAddVideoText(videoTextList);
+        }
     }
 
     @Override
     public void updateVideoSummary(VideoSummary videoSummary) {
         VideoText videoText = new VideoText(videoSummary);
-        videoTextDocument.addOrUpdateVideoText(videoText);
+        if (luceneEnabled) {
+            Document document = luceneDocument.getDocumentByVideoText(videoText);
+            try {
+                luceneIndex.addOrUpdateIndex(indexName, document);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        } else {
+            videoTextDocument.addOrUpdateVideoText(videoText);
+        }
     }
 
     @Override
     public void deleteVideoSummary(String videoId) {
-        videoTextDocument.deleteVideoText(videoId);
+        if (luceneEnabled) {
+            try {
+                luceneIndex.deleteIndex(indexName, videoId);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        } else {
+            videoTextDocument.deleteVideoText(videoId);
+        }
     }
 
     @Override
     public PageList<VideoSummary> searchVideo(String keyword, List<Integer> scopes, int pageNumber) {
-        Page<VideoText> page = videoTextQuery.queryWithHighlight(keyword, scopes, pageNumber);
-        int pageSize = page.getSize();
-        List<VideoSummary> list = page.stream().map(videoText -> {
-            String videoId = videoText.getId();
-            String title = videoText.getTitle();
-            String description = videoText.getDescription();
-            int scope = videoText.getScope();
-            long publishTime = videoText.getPublishTime();
-            return new VideoSummary(videoId, title, description, scope, publishTime);
-        }).collect(Collectors.toList());
-        return PageList.pageList(pageNumber, pageSize, (int) page.getTotalElements(), list);
-    }
+        PageList<VideoSummary> pageList;
+        if (luceneEnabled) {
+            VideoQuery videoQuery = new VideoQuery.Builder()
+                    .pageSize(pageSize)
+                    .pageNumber(pageNumber)
+                    .indexName(indexName)
+                    .queryFiledNames(List.of("title", "description"))
+                    .highlightFiledNames(List.of("title"))
+                    .queryString(keyword)
+                    .scopes(scopes)
+                    .build();
 
-    /**
-     * 使用 ik 分词器对文本进行分词
-     *
-     * @param
-     * @return
-     * @date 2025-03-31 15:35:41
-     */
-    public List<String> segment(String text) {
-        List<String> words = new ArrayList<>();
-        try (StringReader reader = new StringReader(text)) {
-            IKSegmenter segmenter = new IKSegmenter(reader, true);
-            Lexeme lexeme;
-            while ((lexeme = segmenter.next()) != null) {
-                words.add(lexeme.getLexemeText());
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
+            PageList<VideoText> pageList1 = luceneSearch.queryWithHighlight(videoQuery, VideoText.class);
+            List<VideoSummary> list = pageList1.getList().stream().map(this::getVideoSummary).collect(Collectors.toList());
+            pageList = PageList.pageList(pageNumber, pageSize, (int) pageList1.getTotalSize(), list);
+        } else {
+            Page<VideoText> page = videoTextQuery.queryWithHighlight(keyword, scopes, pageNumber);
+            int pageSize = page.getSize();
+            List<VideoSummary> list = page.stream().map(this::getVideoSummary).collect(Collectors.toList());
+            pageList = PageList.pageList(pageNumber, pageSize, (int) page.getTotalElements(), list);
         }
 
-        return words;
+        return pageList;
+    }
+
+    private VideoSummary getVideoSummary(VideoText videoText) {
+        String videoId = videoText.getId();
+        String title = videoText.getTitle();
+        String description = videoText.getDescription();
+        int scope = videoText.getScope();
+        long publishTime = videoText.getPublishTime();
+        return new VideoSummary(videoId, title, description, scope, publishTime);
     }
 }

+ 20 - 9
search/search-service/src/main/java/cn/reghao/tnb/search/app/service/WenshuSearchService.java

@@ -41,8 +41,8 @@ public class WenshuSearchService {
                 .pageSize(pageSize)
                 .pageNumber(pageNumber)
                 .indexName(indexName)
-                .highlightFieldName("caseName")
-                .otherFiledNames(List.of("fullText"))
+                .queryFiledNames(List.of("caseName", "fullText"))
+                .highlightFiledNames(List.of("caseName", "fullText"))
                 .queryString(queryString)
                 .build();
 
@@ -64,8 +64,8 @@ public class WenshuSearchService {
                 .pageSize(pageSize)
                 .pageNumber(pageNumber)
                 .indexName(indexName)
-                .highlightFieldName("caseName")
-                .otherFiledNames(List.of("caseName", "cause", "parties"))
+                .queryFiledNames(List.of("caseName", "fullText"))
+                .highlightFiledNames(List.of("caseName", "fullText"))
                 .queryString(queryString)
                 .build();
         Page<Wenshu> page = queryService.queryWithHighlight(elasticQuery, Wenshu.class);
@@ -75,15 +75,26 @@ public class WenshuSearchService {
         return PageList.pageList(pageNumber, pageSize, total, list);
     }
 
-    public Wenshu queryById(String wenshuId) {
-        //queryService.queryById("wenshu", wenshuId, Wenshu.class);
+    public Wenshu queryById(String wenshuId, String queryString) {
+        String fieldName = "fullText";
         long wenshuIdLong = Long.parseLong(wenshuId);
-        Document document = luceneSearch.findDocumentById("wenshu_lucene", wenshuId);
-        String fullText = document.get("fullText");
+        Document document = luceneSearch.findDocumentById(indexName, wenshuId);
+        String fullText = document.get(fieldName);
+
+        String highlightText = "";
+        try {
+            highlightText = luceneSearch.getHighlightText(fieldName, fullText, queryString);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
 
         WenshuDoc wenshuDoc = wenshuDocRepository.findByWenshuId(wenshuIdLong);
         Wenshu wenshu = new Wenshu(wenshuDoc);
-        wenshu.setFullText(fullText);
+        if (!highlightText.isBlank()) {
+            wenshu.setFullText(highlightText);
+        } else {
+            wenshu.setFullText(fullText);
+        }
         return wenshu;
     }
 }

+ 43 - 0
search/search-service/src/test/java/SearchUnitTest.java

@@ -0,0 +1,43 @@
+import org.junit.jupiter.api.Test;
+import org.wltea.analyzer.core.IKSegmenter;
+import org.wltea.analyzer.core.Lexeme;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2025-08-22 10:28:44
+ */
+public class SearchUnitTest {
+    /**
+     * 使用 ik 分词器对文本进行分词
+     *
+     * @param
+     * @return
+     * @date 2025-03-31 15:35:41
+     */
+    public List<String> segment(String text) {
+        List<String> words = new ArrayList<>();
+        try (StringReader reader = new StringReader(text)) {
+            IKSegmenter segmenter = new IKSegmenter(reader, true);
+            Lexeme lexeme;
+            while ((lexeme = segmenter.next()) != null) {
+                words.add(lexeme.getLexemeText());
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return words;
+    }
+
+    @Test
+    public void segmentTest() throws IOException {
+        String text = "将Field内容进行分词处理后得到的词(或整体Field内容)建立索引, 存储到索引域. **索引的目的是为了搜索. **如: 商品名称, 商品描述需要分词建立索引. 订单编号, 身份证号作为整体建立索引. **只要可能作为用户查询条件的词, 都需要索引. **";
+        List<String> words = segment(text);
+        words.forEach(System.out::println);
+    }
+}

+ 4 - 6
search/search-service/src/test/java/WenshuTest.java

@@ -121,8 +121,8 @@ public class WenshuTest {
                 .pageSize(10)
                 .pageNumber(1)
                 .indexName(indexName)
-                .highlightFieldName("caseName")
-                .otherFiledNames(List.of("caseName", "cause", "parties"))
+                .queryFiledNames(List.of("caseName", "fullText"))
+                .highlightFiledNames(List.of("caseName", "fullText"))
                 .queryString(queryString)
                 .build();
 
@@ -149,14 +149,12 @@ public class WenshuTest {
         int pn = 1;
         int ps = 10;
         String queryString = "拐卖";
-        luceneSearch.search(indexName, queryString, pn, ps);
-
         ElasticQuery elasticQuery = new ElasticQuery.Builder()
                 .pageSize(10)
                 .pageNumber(1)
                 .indexName(indexName)
-                .highlightFieldName("fullText")
-                .otherFiledNames(List.of("caseName"))
+                .queryFiledNames(List.of("caseName", "fullText"))
+                .highlightFiledNames(List.of("caseName", "fullText"))
                 .queryString(queryString)
                 .build();