JAVA course notes series: Data Solr search engine development based on SpringBoot

Posted by del753 on Tue, 14 Jan 2020 06:12:30 +0100

Development of Data Solr search engine based on SpringBoot

About Apache Solr

Solr is an open source search server based on Lucene Java, which is easy to add to Web applications. Solr provides layer search (i.e., statistics), hit and eye-catching display, and supports multiple output formats (including XML/XSLT and JSON). It is easy to install and configure, and comes with an HTTP based management interface. You can use Solr's excellent basic search function, or you can extend it to meet the needs of the enterprise. Solr features include:

  • Advanced full text search capabilities
  • Optimized for high-throughput network traffic
  • Standards based on open interfaces (XML and HTTP)
  • Integrated HTML management interface
  • Scalability - ability to effectively replicate to another Solr search server
  • Use XML configuration for flexibility and adaptability
  • Extensible plug-in system
  • Supports English, German, China, Japan, France and many major languages

The relationship between Apache Solr and Lucene

Solr and Lucene do not compete against each other. On the contrary, Solr depends on Lucene, because the core technology of Solr is implemented by Apache Lucene. In short, Solr is the server of Lucene. It should be noted that Solr does not simply encapsulate Lucene. Most of the functions it provides are different from Lucene.

Apache Solr related directory description

Structure description of Solr package

  • bin: solr related running script
  • docs: relevant API reference documents, wiki materials, etc
  • licenses: solr related certificates are stored
  • contrib: jar package of solr related extension
  • dist: store the JAR file, WAR file and the JAR file that Solr relies on after Solr build.
  • example: is an installed Jetty middleware, including some sample data and Solr configuration information.
  • example/etc: Jetty's configuration file.
  • example/multicore: used to place multiple Solr home directories when Slor multicore is installed.
  • example/solr: the home directory of Solr by default.
  • example/example-DIH: example of database as index data source
  • example/webapps: Solr's WAR file is deployed here.
  • src: Solr related source code.
  • src/java: the Java source of Slor.
  • src/scripts: some Unix bash shell scripts that are useful when large products are released.
  • src/solrj: the Java client of Solr.
  • src/test: Solr's test source and test file.
  • src/webapp: Solr web management interface. The Jsp files of the management interface are all placed under web/admin /. You can modify these files according to your needs.

Solr home directory structure description

  • bin: it is recommended to put the cluster replication script in this directory.
  • conf: place the configuration file.
  • conf/schema.xml: the indexed schema contains the field type definition and its associated parsers.
  • conf/solrconfig.xml: This is Solr's main configuration file.
  • conf/xslt: contains many xslt files, which can convert the query results of Solr's XML to a specific format, such as Atom/RSS.
  • Data: place index data generated by Lucene.
  • lib: place optional JAR files, such as plug-ins for Slor extension, which will be loaded when Solr starts.

Chapter 1: build Apache Solr development environment

Preparation steps: Tomcat 8 and above, JDK7 and above, solr5.5.4

  1. Unzip the Solr package, and copy the folder webapp under solr-5.5.4 \ Solr \
  2. Copy all the jar packages of solr-5.5.4\server\lib\ext in the Solr package to the Tomcat\ webapps\solr\WEB-INF\lib directory
  3. Copy solr-5.5.4\ server\resources \log4j.properties from Solr package to Tomcat\ webapps\solr\WEB-INF directory
  4. Create a solr home directory (the user can decide according to the operating system), and copy all the files except bin in the solr compression package under the example directory D: \ solr home directory, as shown in the figure:

  1. Open web.xml under Tomcat/webapps/solr/WEB-INF and add the following configuration content (the content is commented out in the initial state):
<env-entry>
      <env-entry-name>solr/home</env-entry-name>
      <env-entry-value>D:/solr_home</env-entry-value>
      <env-entry-type>java.lang.String</env-entry-type>
</env-entry>
Change the content in < env entry value > to your Solr home path, here is D: / Solr? Home

This configuration is mainly to establish the relationship between tomcat and solr. Its function is to let tomcat find the solr directory you have configured.
  1. Start tomcat and input the following URL from the address bar: http://localhost:8080/solr, the following interface will appear:

Chapter 2: Apache Solr imports data from MySQL database

  1. Import solr's own data import package and put it into lib under Web inf of solr project in tomcat
    Add the Lib package in the directory of collection1, and copy the package needed for data import to lib
    Including mysql package

  2. Open solrconfig.xml in Solr? Home on disk and add the following code

    <requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
        <lst name="defaults">
          <str name="config">data-config.xml</str>
        </lst>
      </requestHandler>
    

  3. Create a data-config.xml file in the same level directory, and add the following

    <?xml version="1.0" encoding="UTF-8" ?>
    <dataConfig>
    <dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/mydb" user="root" password="root" />
       <document name="userinfo">
           <entity name="userinfo" query="select id,name,address,birthday,age from userinfo ">
               <field column="ID" name="user_id" />
               <field column="NAME" name="user_name" />
               <field column="ADDRESS" name="user_address" />
               <field column="BIRTHDAY" name="user_birthday" />
               <field column="AGE" name="user_age" />
           </entity>
       </document>
    </dataConfig>
    

    Note:

    Document: document representing search engine

    Entity: indicates the corresponding entity class

    Query: executed SQL query statement

    field: the domain corresponding to search engine

    Column: the column corresponding to the database

    Name: domain name corresponding to search engine

  4. Configure the following code under schema.xml in the same level directory, and configure the one-to-one correspondence between the fields and fields of the database.

<field name="user_id" type="int" indexed="true" stored="true"/>
<field name="user_name" type="string" indexed="true" stored="true"/>
<field name="user_address" type="string" indexed="true" stored="true"/>
<field name="user_birthday" type="date" indexed="true" stored="true"/>
<field name="user_age" type="int" indexed="true" stored="true"/>

Chapter 3: Apache Solr configures Chinese word breaker

1. The Chinese word breaker uses Lucene analysts smartcn as the word breaker of Apache Solr, and copies the jar package to webapps Solr under tomcat

In the lib of WEB-INF in the project.

2. Open the managed schema file of conf under the configured collection1 in the configured Solr? Home directory and add the following code

<!-- Add Chinese word breaker -->
<dynamicField name="*_txt_cn" type="text_cn" indexed="true" stored="true"/>
<fieldType name="text_cn" class="solr.TextField">
   <analyzer class="org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer"/>
</fieldType>

Start the console, enter http://localhost:8080/solr from the address bar, and the following interface will appear:

Chapter 4: using spring boot to build solr development environment

The project directory structure is as follows:

Step 1: configure the property file of SpringBoot

spring.data.solr.host=http://localhost:8081/solr
spring.thymeleaf.cache=false
spring.thymeleaf.encoding=utf-8
spring.thymeleaf.mode=HTML
spring.thymeleaf.suffix=.html

Step 2: write the entity class corresponding to Apache Solr

package com.sudojava.springboot_solr.domain;

import org.apache.solr.client.solrj.beans.Field;

public class Product {

    @Field
    private String id;
    @Field
    private String price;
    @Field
    private String title;
    @Field
    private String pic_url;
    @Field
    private String selling_price;
    @Field
    private String sales_volume;
    @Field
    private String coupon_title;

    @Override
    public String toString() {
        return "Product{" +
                "id='" + id + '\'' +
                ", price='" + price + '\'' +
                ", title='" + title + '\'' +
                ", pic_url='" + pic_url + '\'' +
                ", selling_price='" + selling_price + '\'' +
                ", sales_volume='" + sales_volume + '\'' +
                ", coupon_title='" + coupon_title + '\'' +
                '}';
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getPic_url() {
        return pic_url;
    }

    public void setPic_url(String pic_url) {
        this.pic_url = pic_url;
    }

    public String getSelling_price() {
        return selling_price;
    }

    public void setSelling_price(String selling_price) {
        this.selling_price = selling_price;
    }

    public String getSales_volume() {
        return sales_volume;
    }

    public void setSales_volume(String sales_volume) {
        this.sales_volume = sales_volume;
    }

    public String getCoupon_title() {
        return coupon_title;
    }

    public void setCoupon_title(String coupon_title) {
        this.coupon_title = coupon_title;
    }
}

Step 3: write the Service and implementation class of the product query list

package com.sudojava.springboot_solr.service;

import com.sudojava.springboot_solr.domain.Product;

import java.util.List;

public interface ProductService {

    public List<Product> searchProductByName(String title);

}
package com.sudojava.springboot_solr.service;

import com.sudojava.springboot_solr.common.StringTrim;
import com.sudojava.springboot_solr.domain.Product;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

@Service
public class ProductServiceImp implements ProductService {

    @Autowired
    private SolrClient client;

    @Override
    public List<Product> searchProductByName(String title) {
        SolrQuery query = new SolrQuery();
        query.setQuery("title:" + title);
        query.set("df", "title");//Set the domain of the query
        query.setHighlight(true);
        //Set highlighted labels
        query.setHighlightSimplePre("<font color=\"red\">");
        query.setHighlightSimplePost("</font>");
        query.addHighlightField("title");
        query.setHighlightFragsize(150);//Highlighted Title Length
        query.setHighlightSnippets(1);//To obtain the number of highlighted segments, the general search terms may be distributed in different positions in the article, and they are located in a certain length of
        //The statement is a fragment, which is 1 by default, but sometimes it needs to take out several more fragments according to business needs

        QueryResponse response;
        List<Product> list = new ArrayList<>();
        try {
            response = client.query("collection1", query);

            Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();

            if (response.getStatus() == 0) {
                response.getResults().forEach(new Consumer<SolrDocument>() {
                    @Override
                    public void accept(SolrDocument entries) {
                        Product product = new Product();
                        product.setId(StringTrim.trim(entries.get("id")));
                        product.setCoupon_title(StringTrim.trim(entries.get("coupon_title")));
                        product.setPic_url(StringTrim.trim(entries.get("pic_url")));
                        product.setPrice(StringTrim.trim(entries.get("price")));
                        product.setSales_volume(StringTrim.trim(entries.get("sales_volume")));
                        product.setSelling_price(StringTrim.trim(entries.get("selling_price")));
                        Map<String, List<String>> map = highlighting.get(entries.get("id"));
                        List<String> result = map.get("title");
                        if (result != null && result.size() > 0) {
                            product.setTitle(StringTrim.trim(result.get(0)));
                        } else {
                            product.setTitle(StringTrim.trim(entries.get("title")));
                        }

                        list.add(product);
                    }
                });
            }
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }
}

Step 4: write the Controller class, Index initialization page and tool class for product retrieval

package com.sudojava.springboot_solr.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class IndexController {

    @RequestMapping(value = "/",method = RequestMethod.GET)
    public String index(){
        return "/index";
    }
}
package com.sudojava.springboot_solr.controller;

import com.sudojava.springboot_solr.domain.Product;
import com.sudojava.springboot_solr.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.List;

@Controller
public class ProductSearchController {

    @Autowired
    private ProductService service;

    @RequestMapping(value = "/search", method = RequestMethod.POST)
    public String searchProduct(String title, Model model) {
        System.out.println("---title-->>"+title);
        List<Product> list = service.searchProductByName(title);
        System.out.println("----->>" + list);
        model.addAttribute("list", list);
        return "/index";
    }

}
package com.sudojava.springboot_solr.common;

public class StringTrim {

    public static String trim(Object str) {
        if (null == str) {
            str = "";
        }
        return str.toString();
    }
}

Step 5: write the query interface and display the data with the Thymeleaf template engine

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Solr Query product interface</title>

    <meta charset="utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no"/>
    <!--Introduce CSS style-->
    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/>
    <style>
        .mainCSS {
            margin: 0 auto;
            width: 1050px;
        }

        * {
            padding: 0;
            margin: 5px;
            list-style: none;
        }

        html, body {
            width: 100%;
        }

        #wrap {
            width: 1050px;
            margin: 0 auto;
        }

        #wrap ul {
            width: 100%;
            background-color: lightgray;
            box-sizing: border-box;
        }

        #wrap li {
            width: 200px;
            float: left;
            border: 1px solid #000;
            box-sizing: border-box;
        }

        #wrap li img {
            width: 95%;
        }

    </style>
</head>
<body>
<div class="mainCSS">
    <div class="panel panel-primary">
        <div class="panel-heading">
            <h3 class="panel-title">Solr Query product interface</h3>
        </div>
        <div class="panel-body">
            <form class="form-inline" method="post" action="/search" role="form">
                <div class="form-group">
                    <label class="sr-only" for="name"></label>
                    <input type="text"
                           class="form-control" size="120" name="title" id="name"
                           placeholder="Please enter the search content"/>
                </div>
                <button type="submit" class="btn btn-default">search&nbsp;&nbsp;&nbsp;&nbsp;Cable</button>
            </form>
        </div>
    </div>
</div>

<div id="wrap">
    <ul th:each="pro:${list}">

        <li>
            <img th:src="${pro.pic_url}" alt=""/>
            <h5></h5>
            <p>
                <strong>Introduction:</strong><span th:utext="${pro.title}"><span/>
            </p>
            <p style="text-decoration: line-through;color: red;">
                <strong>Original price:</strong><span th:text="${pro.price}"></span>
            </p>
            <p><strong>Selling price:</strong><span th:text="${pro.selling_price}"></span>
            </p>
            <p><strong>Sales volume:</strong><span th:text="${pro.sales_volume}"></span>
            </p>
        </li>

    </ul>
</div>
</body>
</html>

Chapter 5: using SolrClient to add, delete, and modify Solr's index library

This chapter is mainly about unit testing Solr's index library using MockMVC integrated unit testing.

The test steps are as follows:

Step 1: define the operation interface and implementation class for Solr

package com.sudojava.springboot_solr.service;

import com.sudojava.springboot_solr.domain.Product;

import java.util.List;

public interface ProductService {

    public List<Product> searchProductByName(String title);


    public int addProduct(Product product);


    public int deleteProduct(String id);

}
package com.sudojava.springboot_solr.service;

import com.sudojava.springboot_solr.common.StringTrim;
import com.sudojava.springboot_solr.domain.Product;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

@Service
public class ProductServiceImp implements ProductService {

    @Autowired
    private SolrClient client;


    @Override
    public int addProduct(Product product) {
        //The first way to add index
        SolrInputDocument document = new SolrInputDocument();
        document.addField("id", product.getId());
        document.addField("coupon_title", product.getCoupon_title());
        document.addField("pic_url", product.getPic_url());
        document.addField("price", product.getPrice());
        document.addField("sales_volume", product.getSales_volume());
        document.addField("selling_price", product.getSelling_price());
        UpdateResponse response = null;
        try {
            response = client.add("collection1",document);
            if (response.getStatus()==0) {
                client.commit("collection1");
            }
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response.getStatus();
    }


    @Override
    public int deleteProduct(String id) {
        UpdateResponse response = null;
        try {
            response = client.deleteById("collection1",id);
            if (response.getStatus()==0) {
                client.commit("collection1");
            }
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response.getStatus();
    }

    @Override
    public List<Product> searchProductByName(String title) {
        SolrQuery query = new SolrQuery();
        query.setQuery("title:" + title);
        query.set("df", "title");//Set the domain of the query
        query.setHighlight(true);

        //Set highlighted labels
        query.setHighlightSimplePre("<font color=\"red\">");
        query.setHighlightSimplePost("</font>");
        query.addHighlightField("title");
        query.setHighlightFragsize(150);//Highlighted Title Length
        query.setHighlightSnippets(1);//To obtain the number of highlighted segments, the general search terms may be distributed in different positions in the article, and they are located in a certain length of
        //The statement is a fragment, which is 1 by default, but sometimes it needs to take out several more fragments according to business needs

        QueryResponse response;
        List<Product> list = new ArrayList<>();
        try {
            response = client.query("collection1", query);

            Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();

            if (response.getStatus() == 0) {
                response.getResults().forEach(new Consumer<SolrDocument>() {
                    @Override
                    public void accept(SolrDocument entries) {
                        Product product = new Product();
                        product.setId(StringTrim.trim(entries.get("id")));
                        product.setCoupon_title(StringTrim.trim(entries.get("coupon_title")));
                        product.setPic_url(StringTrim.trim(entries.get("pic_url")));
                        product.setPrice(StringTrim.trim(entries.get("price")));
                        product.setSales_volume(StringTrim.trim(entries.get("sales_volume")));
                        product.setSelling_price(StringTrim.trim(entries.get("selling_price")));
                        Map<String, List<String>> map = highlighting.get(entries.get("id"));
                        List<String> result = map.get("title");
                        if (result != null && result.size() > 0) {
                            product.setTitle(StringTrim.trim(result.get(0)));
                        } else {
                            product.setTitle(StringTrim.trim(entries.get("title")));
                        }

                        list.add(product);
                    }
                });
            }
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }
}

Solr also supports the insertion of indexed entity classes

 @Override
    public int addProduct(Product product) {
        //The first way to add index
//        SolrInputDocument document = new SolrInputDocument();
//        document.addField("id", product.getId());
//        document.addField("coupon_title", product.getCoupon_title());
//        document.addField("pic_url", product.getPic_url());
//        document.addField("price", product.getPrice());
//        document.addField("sales_volume", product.getSales_volume());
//        document.addField("selling_price", product.getSelling_price());
        UpdateResponse response = null;
        try {
            response = client.addBean("collection1",product);
            if (response.getStatus()==0) {
                client.commit("collection1");
            }
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response.getStatus();
    }

Step 3: create added and deleted Controller controller

package com.sudojava.springboot_solr.controller;

import com.sudojava.springboot_solr.domain.Product;
import com.sudojava.springboot_solr.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;

@Controller
public class ProductSearchController {

    @Autowired
    private ProductService service;

    @RequestMapping(value = "/search", method = RequestMethod.POST)
    public ModelAndView searchProduct(String title) {
        System.out.println("---title-->>" + title);
        ModelAndView modelAndView = new ModelAndView();
        List<Product> list = service.searchProductByName(title);
        modelAndView.addObject("list", list);
        modelAndView.setViewName("/index");
        return modelAndView;
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String addProduct(Product product, Model model) {
        int flag = service.addProduct(product);
        System.out.println("-------->>"+flag);
        model.addAttribute("flag", "addProduct is success!!!" + flag);
        return "/index";
    }

    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    public String deleteProduct(String  id, Model model) {
        int flag = service.deleteProduct(id);
        System.out.println("-------->>"+flag);
        model.addAttribute("flag", "deleteProduct is success!!!" + flag);
        return "/index";
    }


}

Step 4: create unit test class for test operation

package com.sudojava.springboot_solr;

import com.sudojava.springboot_solr.common.StringTrim;
import com.sudojava.springboot_solr.domain.Product;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.context.WebApplicationContext;

import java.io.IOException;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@SpringBootTest
public class SpringbootSolrApplicationTests {

    private MockMvc mockMvc;

    @Autowired
    private WebApplicationContext context;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
    }


    @Test
    public void searchProduct() throws Exception{
        mockMvc.perform(MockMvcRequestBuilders.post("/search")
        .param("title","Women's wear")
        )
                .andDo(MockMvcResultHandlers.print());
    }

    @Test
    public void deleteProduct() throws Exception{
        mockMvc.perform(MockMvcRequestBuilders.post("/delete")
                .param("id","10010234")
        )
                .andDo(MockMvcResultHandlers.print());
    }


    @Test
    public void add() throws Exception {

        Product product = new Product();
        product.setId("10010234");
        product.setTitle("Clothes are on sale");
        product.setSelling_price("1000");
        product.setSales_volume("200");
        product.setPrice("100");
        product.setCoupon_title("Very good. www");
        product.setPic_url("http://img1.tbcdn.cn/tfscom/i1/TB1qBvJOXXXXXcwapXXXXXXXXXX_!!0-item_pic.jpg_450x10000.jpg");

//        LinkedMultiValueMap<String, String> map = new LinkedMultiValueMap<>();
//        map.add("id", product.getId());
//        map.add("coupon_title", product.getCoupon_title());
//        map.add("pic_url", product.getPic_url());
//        map.add("price", product.getPrice());
//        map.add("sales_volume", product.getSales_volume());
//        map.add("selling_price", product.getSelling_price());

        mockMvc.perform(MockMvcRequestBuilders.post("/add").
                param("id", product.getId()).
                param("coupon_title", product.getCoupon_title()).
                param("pic_url", product.getPic_url()).
                param("price", product.getPrice()).
                param("sales_volume", product.getSales_volume()).
                param("selling_price", product.getSelling_price())
        )
                .andDo(MockMvcResultHandlers.print());
    }

}

Chapter 6: Solr data query based on SpringBoot JPA

This chapter mainly introduces the JPA specification of Solr query in SpringBoot. Spring data provided by spring family is applicable to relational database and nosql database

For example, spring data JPA, spring data Hadoop, spring data mongodb, Spring Data Solr, etc.

Their common feature is to provide us with framework code. spring Data can automatically create the implementation class and custom query of entity dao without us defining it, which simplifies the operation of dao layer.

It is worth noting that if you use the Spring Data Solr operation, you must add a label to the entity class corresponding to Solr

import org.apache.solr.client.solrj.beans.Field;
import org.springframework.data.solr.core.mapping.SolrDocument;

@SolrDocument(solrCoreName = "collection1")
public class Product {
  .......Ellipsis code....
}

Step 1: declare an interface to inherit the solrcudrepository interface

package com.sudojava.springboot_solr.repository;

import com.sudojava.springboot_solr.domain.Product;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.solr.repository.SolrCrudRepository;

public interface ProductRepository extends SolrCrudRepository<Product,String> {
    Page<Product> findByTitle(String title, Pageable pageable);
}

Step 2: declare the corresponding JPA Service, ServiceImp, and Controller classes respectively

package com.sudojava.springboot_solr.jpa;

import com.sudojava.springboot_solr.domain.Product;
import org.springframework.data.domain.Page;

public interface ProductJPAService {

    Page<Product> findByTitle(String title);


    public void addProduct(Product product);

    public void deleteProductByID(String id);
}
package com.sudojava.springboot_solr.jpa;

import com.sudojava.springboot_solr.domain.Product;
import com.sudojava.springboot_solr.repository.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

@Service
public class ProductJPAServiceImp implements ProductJPAService {

    @Autowired
    private ProductRepository repository;

    @Override
    public Page<Product> findByTitle(String title) {

        return repository.findByTitle(title, PageRequest.of(1,6));
    }

    @Override
    public void addProduct(Product product) {
        repository.save(product);
    }

    @Override
    public void deleteProductByID(String id) {
        repository.deleteById(id);
    }
}
package com.sudojava.springboot_solr.jpa;

import com.sudojava.springboot_solr.domain.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class ProductJPASearchController {


    @Autowired
    private ProductJPAService service;

  //Do paging
    @RequestMapping(value = "/jpa/search", method = RequestMethod.POST)
    public String search(String title, Model model) {
        Page<Product> page = service.findByTitle(title);
        model.addAttribute("products", page.getContent());
        model.addAttribute("page", page);
        return "/index";
    }


    @RequestMapping(value = "/jpa/add", method = RequestMethod.POST)
    public String add(Product product) {
        service.addProduct(product);
        return "/index";
    }


    @RequestMapping(value = "/jpa/delete", method = RequestMethod.POST)
    public String delete(String id) {
        service.deleteProductByID(id);
        return "/index";
    }

}

Step 4: declare the unit test class

package com.sudojava.springboot_solr;

import com.sudojava.springboot_solr.common.StringTrim;
import com.sudojava.springboot_solr.domain.Product;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.context.WebApplicationContext;

import java.io.IOException;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@SpringBootTest
public class SpringbootSolrApplicationTests {

    private MockMvc mockMvc;

    @Autowired
    private WebApplicationContext context;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
    }


    @Test
    public void searchProduct() throws Exception{
        mockMvc.perform(MockMvcRequestBuilders.post("/jpa/search")
        .param("title","Women's wear")
        )
                .andDo(MockMvcResultHandlers.print());
    }

    @Test
    public void deleteProduct() throws Exception{
        mockMvc.perform(MockMvcRequestBuilders.post("/delete")
                .param("id","10010234")
        )
                .andDo(MockMvcResultHandlers.print());
    }


    @Test
    public void add() throws Exception {

        Product product = new Product();
        product.setId("10010234");
        product.setTitle("Clothes are on sale");
        product.setSelling_price("1000");
        product.setSales_volume("200");
        product.setPrice("100");
        product.setCoupon_title("Very good. www");
        product.setPic_url("http://img1.tbcdn.cn/tfscom/i1/TB1qBvJOXXXXXcwapXXXXXXXXXX_!!0-item_pic.jpg_450x10000.jpg");

//        LinkedMultiValueMap<String, String> map = new LinkedMultiValueMap<>();
//        map.add("id", product.getId());
//        map.add("coupon_title", product.getCoupon_title());
//        map.add("pic_url", product.getPic_url());
//        map.add("price", product.getPrice());
//        map.add("sales_volume", product.getSales_volume());
//        map.add("selling_price", product.getSelling_price());

        mockMvc.perform(MockMvcRequestBuilders.post("/jpa/add").
                param("id", product.getId()).
                param("coupon_title", product.getCoupon_title()).
                param("pic_url", product.getPic_url()).
                param("price", product.getPrice()).
                param("sales_volume", product.getSales_volume()).
                param("selling_price", product.getSelling_price())
        )
                .andDo(MockMvcResultHandlers.print());
    }

}
219 original articles published, praised 201, 390000 visitors+
His message board follow

Topics: solr Apache Java Spring