Prechádzať zdrojové kódy

智能搜索,阶段1

周壕 9 mesiacov pred
rodič
commit
a214d1c46c

+ 130 - 12
src/main/java/com/bowintek/practice/services/impl/EsQueryServiceImpl.java

@@ -37,25 +37,143 @@ public class EsQueryServiceImpl implements EsQueryService {
         //[1]需要返回的结果map
         Map<String, Object> result = new HashMap<>();
         result.put("total", 0);
-        //[2]分析查询字符串,有的字符串需要变成条件查询
-        List<ComparisonResult> cmpList = analyzeService.analyzeJavas(text);
-        //[3]有查询条件分析内容,组装查询条件
-        List<Query> queryList = new ArrayList<>();
-        for(int i=0;i<cmpList.size();i++){
-            ComparisonResult cmp = cmpList.get(i);
-            if(cmp.getSearchType().equals("comparison")){
-                //对比搜索
 
+        try {
+            //[2]分析查询字符串,有的字符串需要变成条件查询
+            List<ComparisonResult> cmpList = analyzeService.analyzeJavas(text);
+            //[3]有查询条件分析内容,组装查询条件
+            List<Query> queryList = new ArrayList<>();
+            for (int i = 0; i < cmpList.size(); i++) {
+                ComparisonResult cmp = cmpList.get(i);
+                if (cmp.getSearchType().equals("comparison")) {
+                    //第一级,对比搜索
+                    queryList.addAll(getRangeQueryByComparison(cmp));
+                    //第二级,对比搜索
+                    queryList.addAll(getNestedRangeQueryByComparison(cmp, "historys"));
+                } else {
+                    //第一级,文字搜索
+                    queryList.add(getMultiMatchQuery(new String[]{"well_common_name","testing_name"}, cmp.getKeyString()));
+                    //第二级,嵌套类型,文字搜索
+                    queryList.add(getNestedMultiMatchQuery("historys", cmp.getKeyString()));
+                }
             }
-            else{
-                //query 文字搜索
+
+            //[4]建立查询参数分析
+            SearchRequest.Builder searchRequest = new SearchRequest.Builder();
+            //==>要查询的索引列表
+            String[] indexs = new String[]{"dws_basic_info_history", "dws_dm_test_history", "fact_dwr_well_basic_information"};
+            searchRequest.index(Arrays.asList(indexs));
+            //==>数据分页显示
+            searchRequest.size(limit);
+            searchRequest.from(page * limit);
+            //==>设置查询条件
+            if (queryList.size() > 0) {
+                searchRequest.query(q -> q.bool(b -> b.should(queryList)));
             }
-        }
+            //==>高亮设置
+            searchRequest.highlight(h->h.fields("*", f->f.matchedFields("*")));
+
+            //[5]Es发起查询
+            SearchRequest request = searchRequest.build();
+            SearchResponse response = esClient.search(request, ObjectNode.class);
 
+            //[6]转换结果,可以对不同的index做出参数输出
+            List<Map<String, Object>> rows = searchResponse2List(response);
+            result.put("rows", rows);
+            result.put("total", response.hits().total().value());
+            System.out.println(response.hits().total() + " " + request.toString());
+        }
+        catch (Exception ex){
+            result.put("Message", ex.getMessage());
+            result.put("StackTrace", ex.getStackTrace());
+        }
         return result;
     }
 
-    public Map<String, Object> query1(String text, int page, int limit) {
+    public Query getMultiMatchQuery(String text){
+        //不指定,查询所有的一级字段
+        return MultiMatchQuery.of(q -> q.query(text)
+                .operator(Operator.Or))._toQuery();
+    }
+
+    public Query getMultiMatchQuery(List<String> fields, String text){
+        //限定查询字段
+        return MultiMatchQuery.of(q -> q.fields(fields)
+                .query(text)
+                .operator(Operator.Or))._toQuery();
+    }
+
+    public Query getMultiMatchQuery(String[] fields, String text){
+        //限定查询字段
+        return getMultiMatchQuery(Arrays.asList(fields), text);
+    }
+
+    public Query getNestedMultiMatchQuery(String path, String text){
+        //不指定,查询所有的二级字段
+        return NestedQuery.of(q-> q.path(path)
+                .query(getMultiMatchQuery(text))
+                .ignoreUnmapped(true))._toQuery();
+    }
+
+    public Query getNestedMultiMatchQuery(String path, List<String> fields, String text){
+        //限定查询字段
+        return NestedQuery.of(q-> q.path(path)
+                .query(getMultiMatchQuery(fields, text))
+                .ignoreUnmapped(true))._toQuery();
+    }
+
+    public Query getNestedMultiMatchQuery(String path, String[] fields, String text){
+        //限定查询字段
+        return NestedQuery.of(q-> q.path(path)
+                .query(getMultiMatchQuery(fields, text))
+                .ignoreUnmapped(true))._toQuery();
+    }
+
+    public List<Query> getRangeQueryByComparison(ComparisonResult cmp){
+        List<Query> queryList = new ArrayList<>();
+        for(int i=0;i<cmp.getFields().length;i++){
+            String fieldString = cmp.getFields()[i];
+            //对比类型查询
+            Query query = getComparisonQuery(fieldString, cmp.getOpreation(), cmp.getValue());
+            if(query!=null) queryList.add(query);
+        }
+
+        return queryList;
+    }
+
+    public List<Query> getNestedRangeQueryByComparison(ComparisonResult cmp, String path){
+        List<Query> queryList = new ArrayList<>();
+        for(int i=0;i<cmp.getFields().length;i++){
+            String fieldString = cmp.getFields()[i];
+            //对比类型查询
+            Query query = getComparisonQuery(path + "." + fieldString, cmp.getOpreation(), cmp.getValue());
+            if(query!=null) {
+                Query nested = NestedQuery.of(q-> q.path(path).query(query)
+                        .ignoreUnmapped(true))._toQuery();
+                queryList.add(nested);
+            }
+        }
+
+        return queryList;
+    }
+
+    public Query getComparisonQuery(String fieldString, String opreation, String value){
+        //对比类型查询
+        Query query = null;
+        if(opreation.equals("大于"))
+            query = RangeQuery.of(q->q.field(fieldString).gt(JsonData.of(value)))._toQuery();
+        else if(opreation.equals("大于等于"))
+            query = RangeQuery.of(q->q.field(fieldString).gte(JsonData.of(value)))._toQuery();
+        else if(opreation.equals("小于"))
+            query = RangeQuery.of(q->q.field(fieldString).lt(JsonData.of(value)))._toQuery();
+        else if(opreation.equals("小于等于"))
+            query = RangeQuery.of(q->q.field(fieldString).lte(JsonData.of(value)))._toQuery();
+        else if(opreation.equals("等于"))
+            query = TermQuery.of(q->q.field(fieldString).value(value))._toQuery();
+        return query;
+    }
+
+    public Map<String, Object> queryTest(String text, int page, int limit) {
         Map<String, Object> result = new HashMap<>();
         result.put("total", 0);