有两个实体:问题实体(Question)和选项实体(QuestionOption),两个实体间是一对多关系,需求如下:根据问题(questionContent字段)或选项(questionOptionContent字段)进行搜索,并将搜索结果高亮显示。2、所需jar包(gradle项目)
'org.hibernate:hibernate-core:5.0.9.Final','org.hibernate:hibernate-java8:5.0.9.Final','org.hibernate:hibernate-ehcache:5.0.9.Final','org.hibernate:hibernate-entitymanager:5.0.9.Final','org.hibernate:hibernate-search-engine:5.5.4.Final','org.hibernate:hibernate-search-orm:5.5.4.Final','org.apache.lucene:lucene-core:5.3.1','org.apache.lucene:lucene-analyzers-smartcn:5.3.1','org.apache.lucene:lucene-highlighter:5.3.1'3、实体注解如下(具体参照hibernate search 官网):
import java.util.HashSet;import java.util.Set;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.GeneratedValue;import static javax.persistence.GenerationType.IDENTITY;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.JoinTable;import javax.persistence.ManyToMany;import javax.persistence.OneToMany;import javax.persistence.Table;import javax.persistence.UniqueConstraint;import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;import org.hibernate.search.annotations.Analyze;import org.hibernate.search.annotations.Analyzer;import org.hibernate.search.annotations.Field;import org.hibernate.search.annotations.Index;import org.hibernate.search.annotations.Indexed;import org.hibernate.search.annotations.IndexedEmbedded;import org.hibernate.search.annotations.Store;/** * Question generated by hbm2java * updated by 馬輝 2016-11-29 21:46 */@Indexed@Entity@Table(name = "question", catalog = "mryt", uniqueConstraints = @UniqueConstraint(columnNames = "question_sn"))@Analyzer(impl=SmartChineseAnalyzer.class)//分词器public class Question implements java.io.Serializable { PRivate static final long serialVersionUID = 4651161939667149753L; private Integer id; private String questionSn; private String questionContent; private Set<QuestionOption> questionOptions = new HashSet<QuestionOption>(0); @Id @GeneratedValue(strategy = IDENTITY) @Column(name = "id", unique = true, nullable = false) public Integer getId() { return this.id; } public void setId(Integer id) { this.id = id; } @Column(name = "question_sn", unique = true, length = 50) public String getQuestionSn() { return this.questionSn; } public void setQuestionSn(String questionSn) { this.questionSn = questionSn; } @Field(index=Index.YES, analyze=Analyze.YES, store=Store.YES) @Column(name = "questionContent", length = 65535) public String getQuestionContent() { return this.questionContent; } public void setQuestionContent(String questionContent) { this.questionContent = questionContent; } @IndexedEmbedded @OneToMany(targetEntity=QuestionOption.class, fetch = FetchType.LAZY, mappedBy = "question") public Set<QuestionOption> getQuestionOptions() { return this.questionOptions; } public void setQuestionOptions(Set<QuestionOption> questionOptions) { this.questionOptions = questionOptions; }}import java.util.HashSet;import java.util.Set;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;import javax.persistence.OneToMany;import javax.persistence.Table;import javax.persistence.UniqueConstraint;import org.hibernate.search.annotations.Analyze;import org.hibernate.search.annotations.Field;import org.hibernate.search.annotations.Index;import org.hibernate.search.annotations.Indexed;import org.hibernate.search.annotations.Store;/** * QuestionOption generated by hbm2java * updated by 馬輝 2016-11-29 21:48 */@Indexed@Entity@Table(name = "question_option", catalog = "mryt", uniqueConstraints = @UniqueConstraint(columnNames = "question_option_sn"))public class QuestionOption implements java.io.Serializable { private static final long serialVersionUID = 3055805431841974260L; private int id; private Question question; private String questionOptionSn; private String questionOptionContent; private boolean isAnswer; private Set<EmployeeQuestionOption> employeeQuestionOptions = new HashSet<EmployeeQuestionOption>(0); @Id @Column(name = "id", unique = true, nullable = false) public int getId() { return this.id; } public void setId(int id) { this.id = id; } @ManyToOne(targetEntity=Question.class,fetch = FetchType.LAZY) @JoinColumn(name = "question_sn",referencedColumnName="question_sn", nullable = false) public Question getQuestion() { return this.question; } public void setQuestion(Question question) { this.question = question; } @Column(name = "question_option_sn", unique = true, nullable = false, length = 60) public String getQuestionOptionSn() { return this.questionOptionSn; } public void setQuestionOptionSn(String questionOptionSn) { this.questionOptionSn = questionOptionSn; } @Field(index=Index.YES, analyze=Analyze.YES, store=Store.YES) @Column(name = "question_option_content", nullable = false, length = 65535) public String getQuestionOptionContent() { return this.questionOptionContent; } public void setQuestionOptionContent(String questionOptionContent) { this.questionOptionContent = questionOptionContent; } @Column(name = "is_answer", nullable = false) public boolean getIsAnswer() { return isAnswer; } public void setIsAnswer(boolean isAnswer) { this.isAnswer = isAnswer; } @OneToMany(targetEntity=EmployeeQuestionOption.class, fetch = FetchType.LAZY, mappedBy = "questionOption") public Set<EmployeeQuestionOption> getEmployeeQuestionOptions() { return this.employeeQuestionOptions; } public void setEmployeeQuestionOptions(Set<EmployeeQuestionOption> employeeQuestionOptions) { this.employeeQuestionOptions = employeeQuestionOptions; }}4、搜索以及高亮
/** * @method 私有方法(打包高亮问题json) * @param question * @author mahui * @return JSONObject */ private JSONObject packSearchQuestion(Question question,Query luceneQuery,String str){ SimpleHTMLFormatter formatter = new SimpleHTMLFormatter( "<span style='color:red;'>", "</span>"); QueryScorer qs = new QueryScorer(luceneQuery); Highlighter highlighter = new Highlighter( formatter, qs); Analyzer analyzer = new SmartChineseAnalyzer(); JSONObject jsonObject=new JSONObject(); JSONObject qjo=new JSONObject(); qjo.put("questionSn", question.getQuestionSn()); //存放高亮问题 String questionContent=""; try { questionContent = highlighter.getBestFragment(analyzer, str, question.getQuestionContent()); } catch (InvalidTokenOffsetsException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //重新封装问题 if(questionContent!=null&&questionContent.trim().length()>0){ qjo.put("questionContent", questionContent); }else{ qjo.put("questionContent", question.getQuestionContent()); } JSONArray array=new JSONArray(); int i=0; //选项高亮 for(QuestionOption questionOption:question.getQuestionOptions()){ JSONObject jo=new JSONObject(); jo.put("order", (char)('A'+i)); jo.put("optionSn", questionOption.getQuestionOptionSn()); //存放高亮选项 String optionContent=""; try { optionContent = highlighter.getBestFragment(analyzer, str, questionOption.getQuestionOptionContent()); } catch (InvalidTokenOffsetsException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //重新封装选项 if(optionContent!=null&&optionContent.trim().length()>0){ jo.put("optionContent", optionContent); }else{ jo.put("optionContent", questionOption.getQuestionOptionContent()); } jo.put("isAnswer", questionOption.getIsAnswer()); array.add(jo); i++; } jsonObject.put("question", qjo); jsonObject.put("options", array); return jsonObject; } /** * @method 全文检索问题 * @param str * @author mahui * @return JSONArray */ @SuppressWarnings("unchecked") @Override public JSONArray fullTextQuery(String str) { FullTextsession fullTextSession = Search.getFullTextSession(getSession()); List<Question> list=new ArrayList<Question>(); try { fullTextSession.createIndexer().startAndWait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } QueryBuilder qb=fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Question.class).get(); org.apache.lucene.search.Query luceneQuery = qb .keyWord() .onFields("questionContent", "questionOptions.questionOptionContent") .matching(str) .createQuery(); FullTextQuery query = fullTextSession.createFullTextQuery(luceneQuery, Question.class); list=query.setMaxResults(2).list(); JSONArray array=new JSONArray(); for(Question question:list){ array.add(packSearchQuestion(question,luceneQuery,str)); } return array; }
新闻热点
疑难解答