Práctica integral de ElasticSearch

Práctica integral de ElasticSearch

Uno, reptil

Buscar en JD para Java Copiar enlace https://search.jd.com/Search?keyword=java&enc=utf-8
Inserte la descripción de la imagen aquí

F12 para ver el libro debajo de ese div
Inserte la descripción de la imagen aquí

Siguiente información para cada libro
Inserte la descripción de la imagen aquí

Importar dependencias de jsoup

<!--解析网页jsoup-->
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.13.1</version>
        </dependency>

<!--引入阿里巴巴的fastjson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.75</version>
        </dependency>

Cree el paquete de utils y compile la prueba de rastreo HtmlParseUtil.java

//测试数据
public static void main(String[] args) throws IOException, InterruptedException {
    
    
	//获取请求
    String url = "https://search.jd.com/Search?keyword=java";
	// 解析网页 (Jsou返回的Document就是浏览器的Docuement对象)
    Document document = Jsoup.parse(new URL(url), 30000);
    //获取id,所有在js里面使用的方法在这里都可以使用
    Element element = document.getElementById("J_goodsList");
    //获取所有的li元素
    Elements elements = element.getElementsByTag("li");
    //用来计数
    int c = 0;
    //获取元素中的内容  ,这里的el就是每一个li标签
    for (Element el : elements) {
    
    
        c++;
        //这里有一点要注意,直接attr使用src是爬不出来的,因为京东使用了img懒加载
        String img = el.getElementsByTag("img").eq(0).attr("data-lazy-img");
        //获取商品的价格,并且只获取第一个text文本内容
        String price = el.getElementsByClass("p-price").eq(0).text();
        String title = el.getElementsByClass("p-name").eq(0).text();
        String shopName = el.getElementsByClass("p-shop").eq(0).text();

        System.out.println("========================================");
        System.out.println(img);
        System.out.println(price);
        System.out.println(title);
        System.out.println(shopName);
    }
    System.out.println(c);
}

Resultados de la prueba Después de
Inserte la descripción de la imagen aquí
obtener los resultados sin problemas, encapsule este método como una clase de herramienta para su uso

Crea una clase de entidad pojo

Content.java

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Content {
    
    
    private String title;
    private String img;
    private String price;
    //可以自行添加属性
}

Herramientas de embalaje

HtmlParseUtils.java

@Component
public class HtmlParseUtil {
    
    
//    public static void main(String[] args) throws IOException {
    
    
//        new HtmlParseUtil().parseJD("Java").forEach(System.out::println);
//    }

    public List<Content> parseJD(String keywords) throws IOException {
    
    
        //获取请求 https://search.jd.com/Search?keyword=java&enc=utf-8
        //前提需要连网
        String url = "https://search.jd.com/Search?keyword=" + keywords + "&enc=utf-8";
        //解析网页 (Jsoup返回Document就是浏览器Document对象)
        Document document = Jsoup.parse(new URL(url), 30000);
        //所有在js中能使用的方法,这里都能用
        Element element = document.getElementById("J_goodsList");
        //获取所有li元素
        Elements elements = element.getElementsByTag("li");

        ArrayList<Content> goodList = new ArrayList<>();

        //通过元素中的内容,这里el就是每一个li标签了
        for (Element el : elements) {
    
    
            //加if判断是为了 过滤空标签
            if (el.attr("class").equalsIgnoreCase("gl-item")) {
    
    
                //关于这种图片特别多的网页,所有的图片都是延迟加载的
                //在jd搜索后f12可以看到存放在data-lazy-img中
                String img = el.getElementsByTag("img").eq(0).attr("data-lazy-img");
                String price = el.getElementsByClass("p-price").eq(0).text();
                String title = el.getElementsByClass("p-name").eq(0).text();

                Content content = new Content();
                content.setImg(img);
                content.setPrice(price);
                content.setTitle(title);
                goodList.add(content);
            }

        }
        return goodList;
 }
}

Escriba el código de la capa empresarial, elimine la interfaz

ContentService.java

Primero complete un método para almacenar los datos rastreados en ES

//业务编写
@Service
public class ContentService {
    
    
	
	//将客户端注入
    @Autowired
    @Qualifier("restHighLevelClient")
    private RestHighLevelClient client;

    //1、解析数据放到 es 中
    public boolean parseContent(String keyword) throws IOException {
    
    
        List<Content> contents = new HtmlParseUtil().parseJD(keyword);
        //把查询的数据放入 es 中
        BulkRequest request = new BulkRequest();
        request.timeout("2m");

        for (int i = 0; i < contents.size(); i++) {
    
    
            request.add(
                    new IndexRequest("jd_goods")
                            .source(JSON.toJSONString(contents.get(i)), XContentType.JSON));

        }
        BulkResponse bulk = client.bulk(request, RequestOptions.DEFAULT);
        return !bulk.hasFailures();
    }
}

Construir bajo el paquete Controller

ContentController.java

//请求编写
@RestController
public class ContentController {
    
    

    @Autowired
    private ContentService contentService;

    @GetMapping("/parse/{keyword}")
    public Boolean parse(@PathVariable("keyword") String keyword) throws IOException {
    
    
        return contentService.parseContent(keyword);
    }
}

Inicie el proyecto Springboot para acceder a si los datos se pueden rastrear a ES para
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
realizar la función de búsqueda
. Agregue ContentService.java

//2、获取这些数据实现基本的搜索功能
public List<Map<String, Object>> searchPage(String keyword, int pageNo, int pageSize) throws IOException {
    
    
    if (pageNo <= 1) {
    
    
        pageNo = 1;
    }
    if (pageSize <= 1) {
    
    
        pageSize = 1;
    }

    //条件搜索
    SearchRequest searchRequest = new SearchRequest("jd_goods");
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

    //分页
    sourceBuilder.from(pageNo).size(pageSize);

    //精准匹配
    TermQueryBuilder termQuery = QueryBuilders.termQuery("title", keyword);

    sourceBuilder.query(termQuery);
    sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
    //执行搜索
    SearchRequest source = searchRequest.source(sourceBuilder);
    SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
    //解析结果

    List<Map<String, Object>> list = new ArrayList<>();
    for (SearchHit documentFields : searchResponse.getHits().getHits()) {
    
    
        list.add(documentFields.getSourceAsMap());
    }
    return list;
}

Agregue una solicitud de búsqueda en ContentController.java, use RestFul

@GetMapping("/search/{keyword}/{pageNo}/{pageSize}")
public List<Map<String, Object>> search(@PathVariable("keyword") String keyword,
                                        @PathVariable("pageNo") int pageNo,
                                        @PathVariable("pageSize") int pageSize) throws IOException {
    
    
    List<Map<String, Object>> list = contentService.searchPage(keyword, pageNo, pageSize);
    return list;
}

Visite http: // localhost: 9090 / search / java / 1/20 (consulte Java y visualice desde el primero hasta el vigésimo)
Inserte la descripción de la imagen aquí
. No hay ningún problema con el rastreo y la búsqueda de estos datos. Ahora comenzaremos antes y después de la Separación de el final está funcionando

Dos, separación delantera y trasera

Primero importe los recursos preparados e importe los paquetes js de axios, jquery, vue. El
Inserte la descripción de la imagen aquí
front-end necesita aceptar datos

Reciba datos con vue
Inserte la descripción de la imagen aquí

<!--前端使用vue完成前后端分离-->
    <script th:src="@{/js/axios.min.js}"></script>
    <script th:src="@{/js/vue.min.js}"></script>
<script>
    new Vue({
     
     
        el: '#app',
        data: {
     
     
            keyword: '',  //搜索的关键字
            result: []  //搜索的结果
        },
        methods: {
     
     
            searchKey() {
     
     
                var keyword = this.keyword
                axios.get('search/' + keyword + '/1/210').then(response => {
     
     
                    //console.log(response);
                    this.result = response.data;//绑定数据!
            })
            }
        }
    })
</script>

Luego vincule el evento de clic del botón y busque el enlace,
Inserte la descripción de la imagen aquí
use vue para pasar datos al front-end,
Inserte la descripción de la imagen aquí
visite localhost: 9090, busque Java para probar
Inserte la descripción de la imagen aquí

Tres, resaltado de búsqueda

Modificar la función de búsqueda en ContentService.java

//3、获取这些数据实现基本的搜索高亮功能
public List<Map<String, Object>> searchPagehighlighter(String keyword, int pageNo, int pageSize) throws IOException {
    
    
    if (pageNo <= 1) {
    
    
        pageNo = 1;
    }
    if (pageSize <= 1) {
    
    
        pageSize = 1;
    }

    //条件搜索
    SearchRequest searchRequest = new SearchRequest("jd_goods");
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

    //分页
    sourceBuilder.from(pageNo).size(pageSize);

    //精准匹配
    TermQueryBuilder termQuery = QueryBuilders.termQuery("title", keyword);

    //====================================   高   亮   ==========================================
    HighlightBuilder highlightBuilder = new HighlightBuilder(); //获取高亮构造器
    highlightBuilder.field("title"); //需要高亮的字段
    highlightBuilder.requireFieldMatch(false);//不需要多个字段高亮
    highlightBuilder.preTags("<span style='color:red'>"); //前缀
    highlightBuilder.postTags("</span>"); //后缀
    sourceBuilder.highlighter(highlightBuilder); //把高亮构造器放入sourceBuilder中
    sourceBuilder.query(termQuery);
    sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
    //执行搜索
    SearchRequest source = searchRequest.source(sourceBuilder);
    SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
    
    //解析结果
    List<Map<String, Object>> list = new ArrayList<>();
    for (SearchHit hit : searchResponse.getHits().getHits()) {
    
    

        Map<String, HighlightField> highlightFields = hit.getHighlightFields();//获取高亮字段
        HighlightField title = highlightFields.get("title"); //得到我们需要高亮的字段
        Map<String, Object> sourceAsMap = hit.getSourceAsMap();//原来的返回的结果

        //解析高亮的字段
        if (title != null) {
    
    
            Text[] fragments = title.fragments();
            String new_title = "";
            for (Text text : fragments) {
    
    
                new_title += text;
            }
            sourceAsMap.put("title", new_title);  //高亮字段替换掉原来的内容即可
        }
        list.add(sourceAsMap);
    }
    return list;
}

Intente después de cambiar la solicitud de búsqueda en el controlador

@GetMapping("/search/{keyword}/{pageNo}/{pageSize}")
public List<Map<String, Object>> search(@PathVariable("keyword") String keyword,
                                        @PathVariable("pageNo") int pageNo,
                                        @PathVariable("pageSize") int pageSize) throws IOException {
    
    
    List<Map<String, Object>> list = contentService.searchPagehighlighter(keyword, pageNo, pageSize);
    return list;
}

Intento de acceso
Inserte la descripción de la imagen aquí

ok completo
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_43803285/article/details/114806210
Recomendado
Clasificación