solr检索简单使用
1.背景需求
项目中要使用solr进行简单的检索,需要满足一下要求
- 会议地点完全匹配检索
- 会议开始时间与会议结束时间区间检索
- 支持多字段组合关键字检索
- 支持分页
- 支持字段排序
2.solr简单搭建
docker中搭建solr8.4版本的,安装ik分词器,这个步骤就不作详细描述,有需要的参考网上其他安装的文章
solr官方地址:https://solr.apache.org/guide/8_9/query-syntax-and-parsing.html
3.在springboot整合
1.solr依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-solr</artifactId> <version>2.3.2.RELEASE</version> </dependency>
里面集成了solrj,并在springboot-aotuconfigure中自动注入和HttpSolrClient
2.配置文件
spring:
data:
solr:
host: http://127.0.0.1:8983/solr/ikcore
3.java模型模型
import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import org.apache.solr.client.solrj.beans.Field; import org.springframework.data.annotation.Id; import java.io.Serializable; import java.util.Date; import java.util.List; @Data @Builder(toBuilder = true) @NoArgsConstructor @AllArgsConstructor public class AddMeetingRecordDTO extends Model implements Serializable { private static final long serialVersionUID = 6089362063910683619L; public static final String MEETING_ID = "id"; public static final String SUBJECT = "subject"; public static final String START_DATE = "startDate"; public static final String END_DATE = "endDate"; public static final String ROOM_NAME = "roomName"; public static final String LEADER_NAMES = "leaderNames"; public static final String LEADER_IDS = "leaderIds"; public static final String CREATOR_ID = "creatorId"; @Id @Field("id") private String meetingId; @Field("subject") private String subject; @Field("startDate") private Date startDate; @Field("endDate") private Date endDate; @Field("roomName") private String roomName; @Field("leaderNames") private String leaderNames; @Field("leaderIds") private List<String> leaderIds; @Field("attenderNames") private List<String> attenderNames; @Field("attenderIds") private List<String> attenderIds; @Field("detailContent") private String detailContent; @Field("digestContent") private String digestContent; @Field("creatorId") private String creatorId; }
4.solr中域(字段)的定义
<?xml version="1.0" encoding="UTF-8"?> <schema name="default-config" version="1.6"> <!--solr中已定义id域,其他域为自定义--> <field name="id" type="string" multiValued="false" indexed="true" required="true" stored="true"/> <field name="subject" type="text_ik" uninvertible="true" indexed="true" required="true" stored="true"/> <field name="startDate" type="pdate" uninvertible="true" indexed="true" required="true" stored="true"/> <field name="endDate" type="pdate" uninvertible="true" indexed="true" required="true" stored="true"/> <field name="roomName" type="string" uninvertible="true" indexed="true" required="true" stored="true"/> <field name="leaderNames" type="string" uninvertible="true" indexed="true" required="true" stored="true"/> <field name="leaderIds" type="string" uninvertible="true" multiValued="true" indexed="true" required="true" stored="true"/> <field name="attenderNames" type="text_ik" uninvertible="true" multiValued="true" indexed="true" required="true" stored="true"/> <field name="attenderIds" type="string" uninvertible="true" multiValued="true" indexed="true" required="false" stored="true"/> <field name="detailContent" type="text_ik" uninvertible="true" indexed="true" stored="true"/> <field name="digestContent" type="text_ik" uninvertible="true" indexed="true" stored="true"/> <field name="creatorId" type="string" uninvertible="true" indexed="true" required="true" stored="true"/> <!--组合检索字段--> <field name="subject_detail" type="text_ik" uninvertible="true" multiValued="true" indexed="true" stored="true"/> <copyField source="detailContent" dest="subject_detail"/> <copyField source="subject" dest="subject_detail"/> <!--组合检索字段--> <field name="subject_add" type="text_ik" uninvertible="true" multiValued="true" indexed="true" stored="true"/> <copyField source="attenderNames" dest="subject_add"/> <copyField source="detailContent" dest="subject_add"/> <copyField source="digestContent" dest="subject_add"/> <copyField source="subject" dest="subject_add"/> </schema>
这个摘自managed-schema定义中
4.增删改查
1.新增/更新
@Resource private HttpSolrClient solrClient; 1.insert UpdateResponse updateResponse = solrClient.addBean(dto); solrClient.commit(); //这里题主开始没有提交数据,导致插入后一直查不到数据,找了好久的问题 //solr的自动提交可以在配置文件中配置,我是因为没有设置自动提交,所以需要手动提交 2.update(根据id更新某个字段) //solr中如果根据id查询到文档,就会覆盖,查询不到就会新增 HashMap<String, Object> operator = new HashMap<>(); operator.put("set", dto.getDigestContent()); SolrInputDocument doc = new SolrInputDocument(); doc.addField("meetingId", dto.getMeetingId()); doc.addField("digestContent", operator); solrClient.add(doc); solrClient.commit();
2.查询
//1.日期区间检索 StringBuilder builder = new StringBuilder(); builder.append("startDate:[ ").append(startDate.format(datetimeformatter)).append(" TO * ]"); builder.append(" && endDate:[ * TO ").append(endDate.format(datetimeformatter)).append(" ]"); //2.会议地点精确匹配,solr中要完全匹配,需要设置字段类型为string,并且值需要用双引号括起来 if (StrUtil.isNotEmpty(roomName)) { builder.append(" && roomName:\"").append(roomName).append("\""); } //3.分词匹配(相当于mysql中的模糊匹配) if (StrUtil.isNotEmpty(searchField)) { builder.append(" && ").append(searchField).append(":").append(searchFieldValue); } SolrQuery solrQuery = new SolrQuery(); solrQuery.set(CommonParams.Q, builder.toString()); //分页中需要查询总条数total,所以设置开始和条数都为0 solrQuery.setStart(0); solrQuery.setRows(0); long total = solrClient.query(solrQuery).getResults().getNumFound(); if(total > 0){ //solr排序 solrQuery.addSort(sortField, SolrQuery.ORDER.asc); //设置分页数据 solrQuery.setStart((pageNum - 1) * pageSize); solrQuery.setRows(pageSize); //设置需要查询出来的字段 solrQuery.addField(MEETING_ID); solrQuery.addField(SUBJECT); solrQuery.addField(START_DATE); QueryResponse response = solrClient.query(solrQuery); SolrDocumentList documentList = response.getResults(); documentList.forEach(item -> {
//取出数据 String meetingIdStr = (String) item.get(MEETING_ID); String subjectStr = (String) item.get(SUBJECT); Date startDateAlis = (Date) item.get(START_DATE); Date endDateAlis = (Date) item.get(END_DATE); List<String> leaderIdList = (List) item.get(LEADER_IDS); //业务逻辑处理 } }
============over ============
touch fish