Springboot实现ElasticSearch全文模糊搜索(3)

Pom文件

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.68</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
            <version>${elasticsearch.version}</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>${elasticsearch.version}</version>
        </dependency>
    </dependencies>

Controller

public class TestController {
    
    

    @Autowired
    EsClient esClient;

    @PostMapping
    public String commit(@RequestBody JSONObject jsonObject) {
    
    
        log.info(jsonObject.toJSONString());
        esClient.saveIndex("chinese", jsonObject.toJSONString());
        return "ok";
    }

    @GetMapping
    public String query(HttpServletRequest request, @RequestParam(name = "key") String key) {
    
    
        return esClient.query(key);
    }
}

EsClient 类

@Component
@Slf4j
public class EsClient {
    
    
    private static final String INDEX_TYPE = "doc";
    private static final String HOST = "192.168.0.71";
    private RestClient lowClient;
    private RestHighLevelClient highClient;

    public EsClient() {
    
    
        lowClient = RestClient
                .builder(new HttpHost(HOST, 9200, "http"))
                .build();
        highClient = new RestHighLevelClient(RestClient.builder(
                new HttpHost(HOST, 9200, "http")));
    }

    public String saveIndex(String indexName, String jsonData) {
    
    
        try {
    
    
            IndexRequest request = new IndexRequest(indexName, INDEX_TYPE);
            request.source(jsonData, XContentType.JSON);
            IndexResponse indexResponse = highClient.index(request, RequestOptions.DEFAULT);
            log.info(String.format("存储es------>indexName:%s,status:%s,thread:%s", indexName, indexResponse.status(), Thread.currentThread()));
            return indexResponse.status().toString();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        return "";
    }
    private QueryBuilder buildQueryBuilder(String keyword) {
    
    
        QueryBuilder totalBuilder;
        String[] andStr = keyword.split(",");
        String[] orStr = keyword.split(";");
        if (andStr.length > 1) {
    
    
            QueryStringQueryBuilder queryStringQueryBuilder;
            totalBuilder = QueryBuilders.boolQuery();
            for (String s : andStr) {
    
    
                queryStringQueryBuilder = QueryBuilders.queryStringQuery(s).defaultOperator(Operator.AND);
                ((BoolQueryBuilder) totalBuilder).filter(queryStringQueryBuilder);
            }
        } else if (orStr.length > 1) {
    
    
            QueryStringQueryBuilder queryStringQueryBuilder;
            totalBuilder = QueryBuilders.boolQuery();
            for (String s : orStr) {
    
    
                queryStringQueryBuilder = QueryBuilders.queryStringQuery(s).defaultOperator(Operator.AND);
                ((BoolQueryBuilder) totalBuilder).should(queryStringQueryBuilder);
            }
        } else {
    
    
            totalBuilder = QueryBuilders.queryStringQuery(keyword).defaultOperator(Operator.AND);
        }
        return totalBuilder;
    }

    public String querySql(String sql) {
    
    
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("query", "select * from chinese where a=987");
        HttpEntity httpEntity = new NStringEntity(jsonObject.toJSONString(), ContentType.APPLICATION_JSON);
        Request request = new Request("POST", "/_xpack/sql?format=txt");
        request.setEntity(httpEntity);
        try {
    
    
            Response response = lowClient.performRequest(request);
            String str = getInputStream(response.getEntity().getContent());
            return str;
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        return null;
    }
    
    String getInputStream(InputStream inputStream) {
    
    
        BufferedInputStream bis = new BufferedInputStream(inputStream);
        ByteArrayOutputStream buf = new ByteArrayOutputStream();
        int result;
        try {
    
    
            result = bis.read();
            while (result != -1) {
    
    
                buf.write((byte) result);
                result = bis.read();
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }

        return buf.toString();
    }
}

QueryBuilders说明

全局模糊匹配,默认是OR,会将字符切割成一个个单独匹配,如“你好”,会搜出所有包含 “你” 和 “好” 文档
将默认改为AND,只会搜索包含 “你好” 的文档
QueryBuilders.queryStringQuery(s).defaultOperator(Operator.AND);

#这样默认是查询包含“你” 或者 “好” 的所有文档
GET index/doc/_search
{
    
    
  "query": {
    
    
    "query_string": {
    
    
      "query": "你好"
    }
  }
}

1.同时匹配多个字符串 “AND”

 			QueryStringQueryBuilder queryStringQueryBuilder;
            totalBuilder = QueryBuilders.boolQuery();
            for (String s : andStr) {
    
    
                queryStringQueryBuilder = QueryBuilders.queryStringQuery(s).defaultOperator(Operator.AND);
                ((BoolQueryBuilder) totalBuilder).must(queryStringQueryBuilder);
            }

等同于CURL

#查询 同时包含 "你好" 和 "大家好"文档
GET index/doc/_search
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "must": [
        {
    
    
          "query_string": {
    
    
            "query": "你好",
            "default_operator": "AND"
          }
        },
          {
    
    
          "query_string": {
    
    
            "query": "大家好",
            "default_operator": "AND"
          }
        }
      ]
    }
  }
}

2.匹配多个字符串 “OR”

  			 QueryStringQueryBuilder queryStringQueryBuilder;
            totalBuilder = QueryBuilders.boolQuery();
            for (String s : orStr) {
    
    
                queryStringQueryBuilder = QueryBuilders.queryStringQuery(s).defaultOperator(Operator.AND);
                ((BoolQueryBuilder) totalBuilder).should(queryStringQueryBuilder);
            }

等同于CURL

#查询 包含 "你好" 或者 "大家好" 文档
GET index/doc/_search
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "should": [
        {
    
    
          "query_string": {
    
    
            "query": "你好",
            "default_operator": "AND"
          }
        },
          {
    
    
          "query_string": {
    
    
            "query": "大家好",
            "default_operator": "AND"
          }
        }
      ]
    }
  }
}

注意

纯数字,纯英文默认是不带分词的,查找英文单词中部分字母无用。

猜你喜欢

转载自blog.csdn.net/qq_33431394/article/details/107936686