SolrJを使用した検索サービスのインポートと公開

Solrサーバーの構築: http://www.cnblogs.com/liyafei/p/8005571.html

一:検索フィールドのインポート

1:検索対象のフィールドを特定し、SQL文を作成

SELECT

a.id,

b. title

FROM

tb_item a

LEFT JOIN tb_item_cat b ON a.cid = b.id

2:対応するフィールドを受け取るPOJOを作成

public class Product {
    private Long productId;
    private String productName;
    
    // getter and setter methods
}

3:Mapperを作成

<?xml version="1.0" encoding="UTF-8" ?>

<mapper namespace="com.taotao.search.mapper.ProductMapper" >
    <select id="getProductList" resultType="com.taotao.search.pojo.Product">
        SELECT
            a.id,
            b.title
        FROM
            tb_item a
        LEFT JOIN tb_item_cat b ON a.cid = b.id
    </select>
</mapper>

4:Mapperインターフェースを作成

public interface ProductMapper{
    public List<Product> getProductList();
}

5:SolrServerを設定

<bean id="solrServer" class="org.apache.solr.client.solrj.impl.HttpSolrClient">
     <constructor-arg  value="http://192.168.100.91:8080/solr"/>
</bean>

6:Serviceを作成

@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private SolrServer solrServer;
    
    @Override
    public TaotaoResult importProductsToIndex() throws Exception {
        //商品リストをクエリ
        List<Product> productList = productMapper.getProductList();
        //商品リストをSolrにインポート
        for (Product product : productList) {
            SolrInputDocument document = new SolrInputDocument();
            document.addField("id", product.getProductId());
            document.addField("title", product.getProductName());
            //ドキュメントをインデックスに書き込み
            solrServer.add(document);
        }
        //変更をコミット
        solrServer.commit();
        return TaotaoResult.ok();
    }

}

7:Controllerを作成

@Controller
@RequestMapping("/manager")
public class ProductController {

    @Autowired
    private ProductService productService;
    
    @RequestMapping("/importall")
    @ResponseBody
    public TaotaoResult importAll() {
        TaotaoResult result = null;
        try {
            result = productService.importProductsToIndex();
        } catch (Exception e) {
            e.printStackTrace();
            return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));
        }
        return result;
    }
}

二:検索サービスを公開し、他のクライアントから呼び出せるようにする

1:戻り値のPOJO

public class SearchResult {

    private Long totalRecords;
    private List<Product> productList;
    private Integer totalPages;
    private Integer currentPage;
    
}

2:DAO - データベースではなくSolrサーバーからクエリ

@Service
public class ProductSearchDaoImpl implements ProductSearchDao {
    
    @Autowired
    private SolrServer solrServer;

    @Override
    public SearchResult searchProducts(SolrQuery solrQuery) throws Exception {
        //クエリ条件に基づいてインデックスを検索
        QueryResponse response = solrServer.query(solrQuery);
        //商品リストを取得
        SolrDocumentList documentList = response.getResults();
        //商品リスト
        List<Product> productList = new ArrayList<>();
        for (SolrDocument solrDocument : documentList) {
            Product product = new Product();
            product.setId((Long) solrDocument.get("id"));
            //ハイライト表示を取得
            Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
            List<String> highlightList = highlighting.get(solrDocument.get("id")).get("product_title");
            String title = "";
            if (null != highlightList && !highlightList.isEmpty()) {
                title = highlightList.get(0);
            } else {
                title = (String) solrDocument.get("title");
            }
            product.setTitle(title);
            productList.add(product);
        }
        SearchResult result = new SearchResult();
        //商品リスト
        result.setProductList(productList);
        //総レコード数
        result.setTotalRecords(documentList.getNumFound());
        
        return result;
    }

}

3:Service層

@Service
public class ProductSearchServiceImpl implements ProductSearchService {

    @Value("${SEARCH_RESULT_PAGE_SIZE}")
    private Integer PAGE_SIZE;
    @Autowired
    private ProductSearchDao productSearchDao;
    
    @Override
    public SearchResult searchProducts(String queryString, Integer page) throws Exception {
        //クエリオブジェクトを作成
        SolrQuery solrQuery = new SolrQuery();
        //クエリ条件
        if (StringUtils.isBlank(queryString)) {
            solrQuery.setQuery("*:*");
        } else {
            solrQuery.setQuery(queryString);
        }
        //ページング条件
        if (page == null) {
            page = 1;
        }
        solrQuery.setStart((page -1) * PAGE_SIZE);
        solrQuery.setRows(PAGE_SIZE);
        //ハイライト表示
        solrQuery.setHighlight(true);
        //ハイライト表示フィールドを設定
        solrQuery.addHighlightField("title");
        //ハイライト接頭辞
        solrQuery.setHighlightSimplePre("<em style=\"color:red\">");
        //接尾辞
        solrQuery.setHighlightSimplePost("</em>");
        //デフォルト検索フィールドを設定
        solrQuery.set("df", "product_keywords");
        
        //クエリを実行
        SearchResult result = productSearchDao.searchProducts(solrQuery);
        //ページングを計算
        Long totalRecords = result.getTotalRecords();
        int totalPages = (int) (totalRecords / PAGE_SIZE);
        if (totalRecords % PAGE_SIZE > 0) {
            totalPages++;
        }
        result.setTotalPages(totalPages);
        result.setCurrentPage(page);
        
        return result;
    }

}

4:Controller

@Controller
public class ProductSearchController {
    
    @Autowired
    private ProductSearchService productSearchService;

    @RequestMapping("/search")
    @ResponseBody
    public TaotaoResult search(@RequestParam(value = "keyword") String queryString,
            @RequestParam(value = "page", defaultValue = "1") Integer page) {
        
        if (StringUtils.isBlank(queryString)) {
            return TaotaoResult.build(400, "クエリ条件は必須パラメータです");
        }
        SearchResult result = null;
        try {
            result = productSearchService.searchProducts(queryString, page);
             
        } catch (Exception e) {
            e.printStackTrace();
            return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));
        }
        
        return TaotaoResult.ok(result);
    }
}

タグ: SolrJ Apache Solr 検索サービス データインポート Java

6月19日 18:43 投稿