SolrJ 復雜查詢 高亮顯示


SolrJ 復雜查詢 高亮顯示

上一章搭建了Solr服務器和導入了商品數據,本章通過SolrJ去學習Solr在企業中的運用。筆者最先是通過公司的雲客服系統接觸的Solr,幾百萬的留言秒秒鍾就查詢並高亮顯示,不同的廣告員還可以只檢索自己所屬國家的留言。瞬間就跪拜在Solr的石榴裙下。現在看來其實就是 q + fq + lg 的用法。通過本章內容你將會學習到Solr分詞配置;SolrJ的復雜查詢和關鍵字高亮語法;Solr各版本之間SolrJ的語法差異;Solr7與Spring的整合等使用技能。

需求:搜索欄輸入關鍵字全文檢索商品,選擇類目或價格區間篩選商品,選擇價格排序商品。
技術:SolrJ,Spring,SpringMVC
說明:通過本章內容你將會學習到Solr分詞配置;SolrJ的復雜查詢和關鍵字高亮語法;Solr各版本之間SolrJ的語法差異;Solr7與Spring的整合;搜索商品開發思路;本教程頁面來源網絡,筆者做了簡單的修改,僅供學習使用。關注文章底部微信公眾號領紅包哦!
源碼:見文章底部
項目結構:
項目結構

效果圖:
效果圖

Solr分詞配置

solr7 安裝部署:http://www.cnblogs.com/itdragon/p/7995040.html

[tomtop926@localhost lib]$ll IK*
-rw-rw-r--. 1 tomtop926 tomtop926 1165908 Dec  6 15:06 IKAnalyzer2012FF_u1.jar
[tomtop926@localhost lib]$cd ../classes/
[tomtop926@localhost classes]$ll
total 16
-rw-rw-r--. 1 tomtop926 tomtop926  168 Dec  6 15:08 ext_stopword.dic
-rw-rw-r--. 1 tomtop926 tomtop926  419 Dec  6 15:07 IKAnalyzer.cfg.xml
-rw-r--r--. 1 tomtop926 tomtop926 1421 Dec  5 12:09 log4j.properties
-rw-rw-r--. 1 tomtop926 tomtop926   12 Dec  6 15:08 mydict.dic
[tomtop926@localhost classes]$cd 
[tomtop926@localhost ~]$vim solr/apache-tomcat-8.5/solrhome/new_core/conf/managed-schema
<fieldType name="text_ik" class="solr.TextField">
  <analyzer type="index">
    <tokenizer class="org.apache.lucene.analysis.ik.IKTokenizerFactory" useSmart="true"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="org.apache.lucene.analysis.ik.IKTokenizerFactory" useSmart="true"/>
  </analyzer>
</fieldType>
......
<field name="product_catalog" type="string" indexed="true" stored="true"/>
<field name="product_catalog_name" type="string" indexed="true" stored="true"/>
<field name="product_description" type="text_ik" indexed="true" stored="false"/>
<field name="product_name" type="text_ik" indexed="true" stored="true"/>
<field name="product_picture" type="string" indexed="false" stored="true"/>
<field name="product_price" type="pfloat" indexed="true" stored="true"/>
<field name="product_keywords" type="text_ik" multiValued="true" indexed="true" stored="false"/>
<copyField source="product_description" dest="product_keywords"/>
<copyField source="product_name" dest="product_keywords"/>

第一步:將IKAnalyzer2012.jar導入到tomcat/webapps/solr/WEB-INF/lib目錄下
第二步:將ext_stopword.dic(停用詞詞典),IKAnalyzer.cfg.xml(配置文件),mydict.dic(自定義詞典) 導入到tomcat/webapps/solr/WEB-INF/classes
第三步:編輯managed-schema 文件,配置中文分析器
第四步:並配置業務域(solr字段),給product_description,product_name設置中文分詞並放在product_keywords目標域中。下一章會重點介紹schema文件。

SolrJ 單元測試

在采用Solr實現全文檢索功能時,我們需對Solr的java客戶端SolrJ語法有一定的了解。這里創建 SolrJTest.java 類測試SolrJ的連接,查詢,過濾,排序,分頁,高亮等功能,以及索引的維護。

package com.itdragon.test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrQuery.ORDER;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.MapSolrParams;
import org.junit.Test;

public class SolrJTest {
	
	/**
	 * 不同Solr 版本之間創建連接方式不同
	 * Solr4 : SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");  
	 * Solr5 :HttpSolrClient solrClient = new HttpSolrClient("http://localhost:8080/solr/new_core");
	 * Solr7 :HttpSolrClient solrClient = new HttpSolrClient.Builder("http://localhost:8080/solr/new_core").build();
	 * 
	 * SolrQuery 對應的api接口
	 * q : setQuery
	 * fq : addFilterQuery
	 * sort : setSort
	 * start : setStart(0);
	 * rows : setRows(10);
	 * fl : setFields
	 * 
	 */
	
	private final static String BASE_SOLR_URL = "http://localhost:8080/solr/new_core";
	
	// solrJ 基礎用法
	@Test
	public void queryDocumentBasic() throws Exception {
		// 創建連接
		HttpSolrClient solrClient = new HttpSolrClient.Builder(BASE_SOLR_URL).build();
		
		/* 不推薦
		Map<String, String> queryParamMap = new HashMap<String, String>();
		// 封裝查詢參數
		queryParamMap.put("q", "*:*");
        // 添加到SolrParams對象
        MapSolrParams query = new MapSolrParams(queryParamMap);
        */
		
		// 設置查詢條件
        SolrQuery query = new SolrQuery();
		query.setQuery("*:*");
        // 執行查詢
        QueryResponse response = solrClient.query(query);
        // 獲取doc文檔
        SolrDocumentList documents = response.getResults();
		System.out.println("共查詢到記錄:" + documents.getNumFound());
		for (SolrDocument solrDocument : documents) {
			System.out.println("ID : " + solrDocument.get("id") + " \t Name : " + solrDocument.get("product_name"));
		}
	}
	
	// solrJ 的復雜查詢
	@Test
	public void queryDocument() throws Exception {
		// 創建連接
		HttpSolrClient solrClient = new HttpSolrClient.Builder(BASE_SOLR_URL).build();
		SolrQuery query = new SolrQuery();
		// 設置查詢條件
		query.setQuery("product_name:街頭原木電話亭");
		// 設置分頁信息
		query.setStart(0);
		query.setRows(10);
		// 設置排序
		query.setSort("id", ORDER.desc);
		// 設置顯示的Field的域集合,即設置那些值有返回值
		query.setFields("id,product_name");
		// 設置默認域
		query.set("df", "product_keywords");
		// 設置高亮信息
		query.setHighlight(true);
		query.addHighlightField("product_name");
		query.setHighlightSimplePre("<em>");
		query.setHighlightSimplePost("</em>");
		// 執行查詢
		QueryResponse response = solrClient.query(query);
		// 獲取doc文檔
		SolrDocumentList documents = response.getResults();
		System.out.println("共查詢到記錄:" + documents.getNumFound());
		// 獲取高亮顯示信息
		Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
		for (SolrDocument doc : documents) {
			System.out.println(doc.get("id"));
			List<String> hightDocs = highlighting.get(doc.get("id")).get("product_name");
			if (hightDocs != null)
				System.out.println("高亮顯示的商品名稱:" + hightDocs.get(0));
			else {
				System.out.println(doc.get("product_name"));
			}
		}
	}
	
	// 添加索引
	@Test
	public void addDocuments() throws SolrServerException, IOException {
		HttpSolrClient solrClient = new HttpSolrClient.Builder(BASE_SOLR_URL).withConnectionTimeout(10000)
                .withSocketTimeout(60000).build();
		// 創建一個文檔對象
		SolrInputDocument document = new SolrInputDocument();
		document.addField("id", "add-001");
		document.addField("product_name", "ITDragon-Solr7系列博客");
		// 將文檔對象寫入到索引庫中
		solrClient.add(document);
		// 提交
		solrClient.commit();
	}
	
	// 更新的邏輯:先通過id將直接的數據刪掉,然后再創建,所以update 和 create 是同一代碼
	
	// 刪除/批量刪除索引
	@Test
	public void deleteDocument() throws SolrServerException, IOException {
		HttpSolrClient solrClient = new HttpSolrClient.Builder(BASE_SOLR_URL).build();
		//solrClient.deleteById("add-001"); 通過id刪除
		/* 批量刪除
		ArrayList<String> ids = new ArrayList<String>();
        ids.add("1");
        ids.add("2");
        solrClient.deleteById(ids);
        */
		solrClient.deleteByQuery("id:add-001"); // 通過查詢條件刪除
		solrClient.commit();
	}
	
}

SolrJ Web項目

項目構建思路

單元測試通過后,說明核心技術已經掌握,現在開始搭建web項目實現需求。通過Maven 搭建MVC web項目。
第一步:導入SolrJ的jar包,新增用於方便管理 Spring整合Solr的 xml文件。
第二步:創建商品Product實體類。為了方便前端分頁顯示,將查詢的商品實體類集合,查詢的商品總數,總頁數,當前頁封裝到實體類SearchProductResult中。
第三步:為了方便管理SolrJ核心方法。創建SolrSearchDao接口,並實現查詢接口,傳入的參數是SolrQuery,不添加任何業務邏輯。
第四步:創建用於處理業務的ProductService接口,並實現高可用查詢接口。負責拼接查詢條件實現業務邏輯。
第五步:為了提高ProductService 查詢接口的可用性,新增枚舉類FilterQueryKey,管理復雜查詢的key。
第六步:Controller層新增ProductController類,負責接收,返回參數並跳轉頁面。
第七步:頁面展示,通過c:forEach 遍歷查詢結果,fmt:formatNumber格式化價格,以及負責查詢的form表單。

配置文件

Maven 項目核心文件 pom.xml ,導入solrj jar,Solr7對應的SolrJ版本是 7.1.0

<dependency>
	<groupId>org.apache.solr</groupId>
	<artifactId>solr-solrj</artifactId>
	<version>7.1.0</version>
</dependency>

Spring 整合Solr 配置文件 applicationContext-solr.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

	<!-- 配置SolrServer對象 -->
	<!-- 單機版 -->
	<bean id="httpSolrClient" class="org.apache.solr.client.solrj.impl.HttpSolrClient">
	    <constructor-arg name="builder" value="${SOLR.SERVER.URL}"/>
	</bean>
	 
	<bean id="solrSearchDaoImpl" class="com.itdragon.solr.service.impl.SolrSearchDaoImpl" />
</beans>

資源文件 resource.properties

SOLR.SERVER.URL=http://localhost:8080/solr/new_core

實體類

這里有三個文件,一個是商品類 Product.java ,一個是返回參數封裝類 SearchProductResult.java ,一個是管理查詢key的枚舉類FilterQueryKey.java

package com.itdragon.mapper.pojo;

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

public class Product {
    
    @Field
    private String id;				// 商品編號
    @Field
    private String name; 			// 商品名稱
    @Field
    private String catalog_name; 	// 商品分類名稱
    @Field
    private Float price;			// 價格
    @Field
    private Long number;			// 數量
    @Field
    private String picture;			//圖片名稱
    @Field
    private String description;		// 商品描述

    // get,set 方法省略

}
import java.util.List;

public class SearchProductResult {

	private List<Product> productList;	// 商品列表
	private Long recordCount;	// 商品總數
	private Integer pageCount;	// 總頁數
	private Integer curPage;	// 當前頁

	// get,set 方法省略

}
package com.itdragon.mapper.pojo;

public enum FilterQueryKey {
	
	PRICE("price"), // 價格
	CATALOG_NAME("catalog_name"), // 類目名
	SORT("sort"); // 價格排序
	
	private String value;

	private FilterQueryKey(String value) {
		this.value = value;
	}

	public String getValue() {
		return value;
	}

	public static FilterQueryKey fromValue(String v) {
        for (FilterQueryKey c: FilterQueryKey.values()) {
            if (c.value.equals(v)) {
                return c;
            }
        }
        throw new IllegalArgumentException(v);
    }

}

Dao 層

提供了SolrJ的查詢接口及其實現類 SolrSearchDaoImpl.java ,這里不要有任何業務相關的代碼。這里需要注意關鍵詞高亮顯示。在Solr管理頁面分析高亮返回的機構,以方便獲取對應的值。
高亮的結構

package com.itdragon.solr.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.CollectionUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.springframework.beans.factory.annotation.Autowired;
import com.itdragon.mapper.pojo.Product;
import com.itdragon.mapper.pojo.SearchProductResult;
import com.itdragon.solr.service.SolrSearchDao;

public class SolrSearchDaoImpl implements SolrSearchDao {
	
	@Autowired
	private HttpSolrClient httpSolrClient;

	@Override
	public SearchProductResult search(SolrQuery query) throws Exception {
		// 返回值對象
		SearchProductResult result = new SearchProductResult();
		// 根據查詢條件查詢索引庫
		System.out.println("solr Query : " + query);
		QueryResponse queryResponse = httpSolrClient.query(query);
		// 獲取查詢結果
		SolrDocumentList solrDocumentList = queryResponse.getResults();
		// 獲取查詢結果總數量
		result.setRecordCount(solrDocumentList.getNumFound());
		// 初始化返回結果商品列表
		List<Product> products = new ArrayList<>();
		// 獲取高亮顯示數據
		Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
		// 遍歷查詢結果
		for (SolrDocument solrDocument : solrDocumentList) {
			Product product = new Product();
			product.setId((String) solrDocument.get("id"));
			// 獲取高亮顯示的集合
			List<String> hightNames = highlighting.get(solrDocument.get("id")).get("product_name");
			String pName = CollectionUtils.isNotEmpty(hightNames)? hightNames.get(0) : (String) solrDocument.get("product_name");
			product.setName(pName);
			product.setPicture((String) solrDocument.get("product_picture"));
			product.setPrice((float) solrDocument.get("product_price"));
			product.setCatalog_name((String) solrDocument.get("product_category_name"));
			products.add(product);
		}
		result.setProductList(products);
		return result;
	}

}

Service 層

提供了根據業務需求邏輯查詢商品的接口及其實現類 ProductServiceImpl.java

package com.itdragon.service.impl;

import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrQuery.ORDER;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.itdragon.mapper.pojo.FilterQueryKey;
import com.itdragon.mapper.pojo.SearchProductResult;
import com.itdragon.service.ProductService;
import com.itdragon.solr.service.SolrSearchDao;

@Service
public class ProductServiceImpl implements ProductService {
	
	@Autowired
	private SolrSearchDao solrSearchDao;

	@Override
	public SearchProductResult search(String queryString, Map<String, String> filterQueryMap, Integer page, Integer rows) throws Exception {
		// 創建查詢對象
		SolrQuery query = new SolrQuery();
		// 設置查詢條件
		queryString = StringUtils.isEmpty(queryString)? "*:*" : queryString;
		query.setQuery(queryString);
		// 設置復雜查詢條件
		if (null != filterQueryMap.get(FilterQueryKey.CATALOG_NAME.getValue())) {
			query.addFilterQuery("product_catalog_name:" + filterQueryMap.get(FilterQueryKey.CATALOG_NAME.getValue()));
		}
		if (null != filterQueryMap.get(FilterQueryKey.PRICE.getValue())) {
			String price = filterQueryMap.get(FilterQueryKey.PRICE.getValue());
			query.addFilterQuery("product_price:[" + price.split("-")[0] + " TO " + price.split("-")[1] + "]");
		}
		if (null != filterQueryMap.get(FilterQueryKey.SORT.getValue())) {
			String priceSort = filterQueryMap.get(FilterQueryKey.SORT.getValue());
			query.setSort("product_price", "1".equals(priceSort) ? ORDER.desc : ORDER.asc);
		}
		// 設置分頁
		query.setStart((page - 1) * rows); // 當前頁面開始下標
		query.setRows(rows);
		// 設置默認搜素域
		query.set("df", "product_keywords");
		// 設置高亮顯示
		query.setHighlight(true);
		query.addHighlightField("product_name");
		query.setHighlightSimplePre("<em style=\"color:red\">");
		query.setHighlightSimplePost("</em>");
		// 執行查詢
		SearchProductResult searchResult = solrSearchDao.search(query);
		// 計算查詢結果總頁數
		long recordCount = searchResult.getRecordCount();
		int pageCount = (int) (recordCount % rows > 0? (recordCount / rows) + 1 : (recordCount / rows));
		searchResult.setPageCount(pageCount);
		searchResult.setCurPage(page);
		
		return searchResult;
	}

}

Controller 層

實現主頁初始化和檢索功能

package com.itdragon.controller;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
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.RequestParam;
import com.itdragon.mapper.pojo.FilterQueryKey;
import com.itdragon.mapper.pojo.SearchProductResult;
import com.itdragon.service.ProductService;

@Controller
public class ProductController {
	
	@Autowired
	private ProductService searchService;
	
	@RequestMapping("/")
	public String showIndex(Model model) {
		SearchProductResult searchResult;
		try {
			searchResult = searchService.search("*:*", new HashMap<>(), 1, 12);
			model.addAttribute("result", searchResult);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "index";
	}
	
	@RequestMapping(value="/query")
	public String search(@RequestParam("queryString")String query, 
			@RequestParam("catalog_name") String catalog_name, 
			@RequestParam("price") String price,
			@RequestParam("sort") String sort,
			@RequestParam(defaultValue="1")Integer page, 
			@RequestParam(defaultValue="12")Integer rows, Model model) {
		SearchProductResult searchResult = null;
		try {
			// 拼接復雜的查詢語句
			Map<String, String> filterQueryMap = new HashMap<>();
			if (StringUtils.isNotBlank(catalog_name)) {
				filterQueryMap.put(FilterQueryKey.CATALOG_NAME.getValue(), catalog_name);
			}
			if (StringUtils.isNotBlank(price)) {
				filterQueryMap.put(FilterQueryKey.PRICE.getValue(), price);
			}
			if (StringUtils.isNotBlank(sort)) {
				filterQueryMap.put(FilterQueryKey.SORT.getValue(), sort);
			}
			searchResult = searchService.search(query, filterQueryMap, page, rows);
			model.addAttribute("result", searchResult);
			model.addAttribute("queryString", query);
			model.addAttribute("catalog_name", catalog_name);
			model.addAttribute("price", price);
			model.addAttribute("sort", sort);
			model.addAttribute("page", page);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "index";	
	}

}

View 層

實現點擊搜索框進行查詢,點擊類目篩選查詢,點擊價格區間查詢,點擊價格排序,查詢結果回顯,分頁的功能。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
......省略
<script type="text/javascript">
	// 關鍵字查詢
	function query() {
		//執行關鍵詞查詢時清空過濾條件
		document.getElementById("catalog_name").value="";
		document.getElementById("price").value="";
		document.getElementById("page").value="";
		queryList();
	}
	// 表單提交
	function queryList() {
		document.getElementById("actionForm").submit();
	}
	// 特殊值查詢
	function filter(key, value) {
		document.getElementById(key).value=value;
		queryList();
	}
	// 排序
	function sort() {
		var s = document.getElementById("sort").value;
		if (s != "1") {
			s = "1";
		} else {
			s = "0";
		}
		document.getElementById("sort").value = s;
		queryList();
	}
	// 翻頁
	function changePage(p) {
		var curpage = Number(document.getElementById("page").value);
		curpage = curpage + p;
		document.getElementById("page").value = curpage;
		queryList();
	}
</script>
</head>
<body class="root61">
......省略
<div id="o-header-2013">
	<div class="w" id="header-2013">
		<div id="logo-2013" class="ld"><a href="#" hidefocus="true"><b></b><img src="" width="270" height="60" alt="Logo"></a></div>
		<!--logo end-->
		<div id="search-2013">
			<div class="i-search ld">
				<ul id="shelper" class="hide"></ul>
				<form id="actionForm" action="/query" method="POST">
				<div class="form">
					<input type="text" class="text" accesskey="s" name="queryString" id="key" value="${queryString}"
						autocomplete="off" onkeydown="javascript:if(event.keyCode==13) {query()}">
					<input type="button" value="搜索" class="button" onclick="query()">
				</div>
				<input type="hidden" name="catalog_name" id="catalog_name" value="${catalog_name}"/> 
				<input type="hidden" name="price" id="price" value="${price}"/> 
				<input type="hidden" name="page" id="page" value="${result.curPage}"/> 
				<input type="hidden" name="sort" id="sort" value="${sort}"/> 
				</form>
			</div>
			<div id="hotwords"></div>
		</div>
		<!--search end-->
	</div>
	<!--header end-->
	......省略
</div>
<div class="w">
	<div class="breadcrumb">
		<strong><a href="#">服飾內衣</a></strong><span>&nbsp;&gt;&nbsp;<a href="#">女裝</a>&nbsp;&gt;&nbsp;<a href="#">T恤</a></span>
	</div>
</div>
<div class="w main">
<div class="right-extra">
<div id="select" clstag="thirdtype|keycount|thirdtype|select" class="m">
	<div class="mt">
		<h1>T恤 -<strong>&nbsp;商品篩選</strong></h1>
	</div>
	<!-- 類目查詢和價格區間查詢 -->
	<div class="mc attrs">
		<div data-id="100001" class="brand-attr">
			<div class="attr">
				<div class="a-key">商品類別:</div>
				<div class="a-values">
					<div class="v-tabs">
						<div class="tabcon">
							<div><a href="javascript:filter('catalog_name', '幽默雜貨')">幽默雜貨</a></div>
							<div><a href="javascript:filter('catalog_name', '時尚衛浴')">時尚衛浴</a></div>
							<div><a href="javascript:filter('catalog_name', '另類文體')">另類文體</a></div>
							<div><a href="javascript:filter('catalog_name', '創意相架')">創意相架</a></div>
							<div><a href="javascript:filter('catalog_name', '巧妙收納')">巧妙收納</a></div>
						</div>
					</div>
				</div>
			</div>
		</div>
		<div data-id="100002" class="prop-attrs">
			<div class="attr">
				<div class="a-key">價格:</div>
				<div class="a-values">
					<div class="v-fold">
						<ul class="f-list">
							<li><a href="javascript:filter('price','0-9')">0-9</a></li>
							<li><a href="javascript:filter('price','10-29')">10-29</a></li>
							<li><a href="javascript:filter('price','30-49')">30-49</a></li>
							<li><a href="javascript:filter('price','50-*')">50以上</a></li>
						</ul>
					</div>
				</div>
			</div>
		</div>
	</div>
</div>
<!-- 價格排序,分頁 -->
<div id="filter">
	<div class="cls"></div>
	<div class="fore1">
		<dl class="order">
			<dt>排序:</dt>
			<dd><a href="javascript:sort()">價格</a><b></b></dd>
		</dl>
		<dl class="activity">
			<dd></dd>
		</dl>
		<div class="pagin pagin-m">
			<span class="text"><i>${result.curPage }</i>/${result.pageCount }</span>
			<a href="javascript:changePage(-1)" class="prev">上一頁<b></b></a>
			<a href="javascript:changePage(1)" class="next">下一頁<b></b></a>
		</div>
		<div class="total">
			<span>共<strong>${result.recordCount }</strong>個商品
			</span>
		</div>
		<span class="clr"></span>
	</div>
</div>
<!--核心代碼,商品列表開始-->
<div id="plist" class="m plist-n7 plist-n8 prebuy">
	<ul class="list-h">
		<c:forEach var="item" items="${result.productList }">
		<li pid="${item.id }">
			<div class="lh-wrap">
				<div class="p-img">
					<a target="_blank" href="#">
						<img width="220" height="282" class="err-product" src="/images/${item.picture}">
					</a>
				</div>
				<div class="p-name">
					<a target="_blank" href="#">${item.name }</a>
				</div>
				<div class="p-price">
					<strong>¥<fmt:formatNumber value="${item.price}" maxFractionDigits="2"/>
				</div>
			</div>
		</li>
		</c:forEach>
	</ul>
</div>
......省略
</body>
</html>

總結

  • SolrJ連接solr全文檢索服務器,實現查詢,攔截,排序,分頁,高亮等功能。
  • Spring整合SolrJ實現電商商品頁面檢索,篩選,分頁功能。

源碼:https://github.com/ITDragonBlog/daydayup/tree/master/Solr/ssm-solr

到這里SolrJ 復雜查詢 高亮顯示就結束了。有什么不對的地方請指出,最后感謝閱讀!如果覺得文章不錯,麻煩點一下"推薦"


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM