Hibernate Search使用以及搜索结果高亮显示

原文地址:https://blog.csdn.net/qq_33663251/article/details/54928478

Hibernate Search使用以及搜索结果高亮显视

 

1、首先说一下需求

有两个实体:问题实体(Question)和选项实体(QuestionOption),两个实体间是一对多关系,需求如下:根据问题(questionContent字段)或选项(questionOptionContent字段)进行搜索,并将搜索结果高亮显示。

 

 

2、所需jar包(gradle项目)

 
  1. 'org.hibernate:hibernate-core:5.0.9.Final',

  2. 'org.hibernate:hibernate-java8:5.0.9.Final',

  3. 'org.hibernate:hibernate-ehcache:5.0.9.Final',

  4. 'org.hibernate:hibernate-entitymanager:5.0.9.Final',

  5. 'org.hibernate:hibernate-search-engine:5.5.4.Final',

  6. 'org.hibernate:hibernate-search-orm:5.5.4.Final',

  7. 'org.apache.lucene:lucene-core:5.3.1',

  8. 'org.apache.lucene:lucene-analyzers-smartcn:5.3.1',

  9. 'org.apache.lucene:lucene-highlighter:5.3.1'

3、实体注解如下(具体参照hibernate search 官网):

 
  1. import java.util.HashSet;

  2. import java.util.Set;

  3. import javax.persistence.Column;

  4. import javax.persistence.Entity;

  5. import javax.persistence.FetchType;

  6. import javax.persistence.GeneratedValue;

  7. import static javax.persistence.GenerationType.IDENTITY;

  8. import javax.persistence.Id;

  9. import javax.persistence.JoinColumn;

  10. import javax.persistence.JoinTable;

  11. import javax.persistence.ManyToMany;

  12. import javax.persistence.OneToMany;

  13. import javax.persistence.Table;

  14. import javax.persistence.UniqueConstraint;

  15.  
  16. import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;

  17. import org.hibernate.search.annotations.Analyze;

  18. import org.hibernate.search.annotations.Analyzer;

  19. import org.hibernate.search.annotations.Field;

  20. import org.hibernate.search.annotations.Index;

  21. import org.hibernate.search.annotations.Indexed;

  22. import org.hibernate.search.annotations.IndexedEmbedded;

  23. import org.hibernate.search.annotations.Store;

  24.  
  25. /**

  26. * Question generated by hbm2java

  27. * updated by 馬輝 2016-11-29 21:46

  28. */

  29. @Indexed

  30. @Entity

  31. @Table(name = "question", catalog = "mryt", uniqueConstraints = @UniqueConstraint(columnNames = "question_sn"))

  32. @Analyzer(impl=SmartChineseAnalyzer.class)//分词器

  33. public class Question implements java.io.Serializable {

  34. private static final long serialVersionUID = 4651161939667149753L;

  35. private Integer id;

  36. private String questionSn;

  37. private String questionContent;

  38. private Set<QuestionOption> questionOptions = new HashSet<QuestionOption>(0);

  39.  
  40. @Id

  41. @GeneratedValue(strategy = IDENTITY)

  42.  
  43. @Column(name = "id", unique = true, nullable = false)

  44. public Integer getId() {

  45. return this.id;

  46. }

  47.  
  48. public void setId(Integer id) {

  49. this.id = id;

  50. }

  51.  
  52. @Column(name = "question_sn", unique = true, length = 50)

  53. public String getQuestionSn() {

  54. return this.questionSn;

  55. }

  56.  
  57. public void setQuestionSn(String questionSn) {

  58. this.questionSn = questionSn;

  59. }

  60.  
  61. @Field(index=Index.YES, analyze=Analyze.YES, store=Store.YES)

  62. @Column(name = "questionContent", length = 65535)

  63. public String getQuestionContent() {

  64. return this.questionContent;

  65. }

  66.  
  67. public void setQuestionContent(String questionContent) {

  68. this.questionContent = questionContent;

  69. }

  70.  
  71. @IndexedEmbedded

  72. @OneToMany(targetEntity=QuestionOption.class, fetch = FetchType.LAZY, mappedBy = "question")

  73. public Set<QuestionOption> getQuestionOptions() {

  74. return this.questionOptions;

  75. }

  76.  
  77. public void setQuestionOptions(Set<QuestionOption> questionOptions) {

  78. this.questionOptions = questionOptions;

  79. }

  80.  
  81. }

 
  1. import java.util.HashSet;

  2. import java.util.Set;

  3. import javax.persistence.Column;

  4. import javax.persistence.Entity;

  5. import javax.persistence.FetchType;

  6. import javax.persistence.Id;

  7. import javax.persistence.JoinColumn;

  8. import javax.persistence.ManyToOne;

  9. import javax.persistence.OneToMany;

  10. import javax.persistence.Table;

  11. import javax.persistence.UniqueConstraint;

  12.  
  13. import org.hibernate.search.annotations.Analyze;

  14. import org.hibernate.search.annotations.Field;

  15. import org.hibernate.search.annotations.Index;

  16. import org.hibernate.search.annotations.Indexed;

  17. import org.hibernate.search.annotations.Store;

  18.  
  19. /**

  20. * QuestionOption generated by hbm2java

  21. * updated by 馬輝 2016-11-29 21:48

  22. */

  23. @Indexed

  24. @Entity

  25. @Table(name = "question_option", catalog = "mryt", uniqueConstraints = @UniqueConstraint(columnNames = "question_option_sn"))

  26. public class QuestionOption implements java.io.Serializable {

  27. private static final long serialVersionUID = 3055805431841974260L;

  28. private int id;

  29. private Question question;

  30. private String questionOptionSn;

  31. private String questionOptionContent;

  32. private boolean isAnswer;

  33. private Set<EmployeeQuestionOption> employeeQuestionOptions = new HashSet<EmployeeQuestionOption>(0);

  34.  
  35. @Id

  36. @Column(name = "id", unique = true, nullable = false)

  37. public int getId() {

  38. return this.id;

  39. }

  40.  
  41. public void setId(int id) {

  42. this.id = id;

  43. }

  44.  
  45. @ManyToOne(targetEntity=Question.class,fetch = FetchType.LAZY)

  46. @JoinColumn(name = "question_sn",referencedColumnName="question_sn", nullable = false)

  47. public Question getQuestion() {

  48. return this.question;

  49. }

  50.  
  51. public void setQuestion(Question question) {

  52. this.question = question;

  53. }

  54.  
  55. @Column(name = "question_option_sn", unique = true, nullable = false, length = 60)

  56. public String getQuestionOptionSn() {

  57. return this.questionOptionSn;

  58. }

  59.  
  60. public void setQuestionOptionSn(String questionOptionSn) {

  61. this.questionOptionSn = questionOptionSn;

  62. }

  63.  
  64. @Field(index=Index.YES, analyze=Analyze.YES, store=Store.YES)

  65. @Column(name = "question_option_content", nullable = false, length = 65535)

  66. public String getQuestionOptionContent() {

  67. return this.questionOptionContent;

  68. }

  69.  
  70. public void setQuestionOptionContent(String questionOptionContent) {

  71. this.questionOptionContent = questionOptionContent;

  72. }

  73.  
  74. @Column(name = "is_answer", nullable = false)

  75. public boolean getIsAnswer() {

  76. return isAnswer;

  77. }

  78.  
  79. public void setIsAnswer(boolean isAnswer) {

  80. this.isAnswer = isAnswer;

  81. }

  82.  
  83. @OneToMany(targetEntity=EmployeeQuestionOption.class, fetch = FetchType.LAZY, mappedBy = "questionOption")

  84. public Set<EmployeeQuestionOption> getEmployeeQuestionOptions() {

  85. return this.employeeQuestionOptions;

  86. }

  87.  
  88. public void setEmployeeQuestionOptions(Set<EmployeeQuestionOption> employeeQuestionOptions) {

  89. this.employeeQuestionOptions = employeeQuestionOptions;

  90. }

  91.  
  92. }

4、搜索以及高亮 

 
  1. /**

  2. * @method 私有方法(打包高亮问题json)

  3. * @param question

  4. * @author mahui

  5. * @return JSONObject

  6. */

  7. private JSONObject packSearchQuestion(Question question,Query luceneQuery,String str){

  8. SimpleHTMLFormatter formatter = new SimpleHTMLFormatter( "<span style='color:red;'>", "</span>");

  9. QueryScorer qs = new QueryScorer(luceneQuery);

  10. Highlighter highlighter = new Highlighter( formatter, qs);

  11. Analyzer analyzer = new SmartChineseAnalyzer();

  12.  
  13. JSONObject jsonObject=new JSONObject();

  14.  
  15. JSONObject qjo=new JSONObject();

  16. qjo.put("questionSn", question.getQuestionSn());

  17. //存放高亮问题

  18. String questionContent="";

  19. try {

  20. questionContent = highlighter.getBestFragment(analyzer, str, question.getQuestionContent());

  21. } catch (InvalidTokenOffsetsException e) {

  22. e.printStackTrace();

  23. } catch (IOException e) {

  24. e.printStackTrace();

  25. }

  26. //重新封装问题

  27. if(questionContent!=null&&questionContent.trim().length()>0){

  28. qjo.put("questionContent", questionContent);

  29. }else{

  30. qjo.put("questionContent", question.getQuestionContent());

  31. }

  32.  
  33. JSONArray array=new JSONArray();

  34. int i=0;

  35. //选项高亮

  36. for(QuestionOption questionOption:question.getQuestionOptions()){

  37. JSONObject jo=new JSONObject();

  38. jo.put("order", (char)('A'+i));

  39. jo.put("optionSn", questionOption.getQuestionOptionSn());

  40.  
  41. //存放高亮选项

  42. String optionContent="";

  43. try {

  44. optionContent = highlighter.getBestFragment(analyzer, str, questionOption.getQuestionOptionContent());

  45. } catch (InvalidTokenOffsetsException e) {

  46. e.printStackTrace();

  47. } catch (IOException e) {

  48. e.printStackTrace();

  49. }

  50. //重新封装选项

  51. if(optionContent!=null&&optionContent.trim().length()>0){

  52. jo.put("optionContent", optionContent);

  53. }else{

  54. jo.put("optionContent", questionOption.getQuestionOptionContent());

  55. }

  56. jo.put("isAnswer", questionOption.getIsAnswer());

  57. array.add(jo);

  58. i++;

  59. }

  60.  
  61. jsonObject.put("question", qjo);

  62. jsonObject.put("options", array);

  63. return jsonObject;

  64. }

  65.  
  66. /**

  67. * @method 全文检索问题

  68. * @param str

  69. * @author mahui

  70. * @return JSONArray

  71. */

  72. @SuppressWarnings("unchecked")

  73. @Override

  74. public JSONArray fullTextQuery(String str) {

  75. FullTextSession fullTextSession = Search.getFullTextSession(getSession());

  76. List<Question> list=new ArrayList<Question>();

  77. try {

  78. fullTextSession.createIndexer().startAndWait();

  79. } catch (InterruptedException e) {

  80. // TODO Auto-generated catch block

  81. e.printStackTrace();

  82. }

  83. QueryBuilder qb=fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Question.class).get();

  84. org.apache.lucene.search.Query luceneQuery = qb

  85. .keyword()

  86. .onFields("questionContent", "questionOptions.questionOptionContent")

  87. .matching(str)

  88. .createQuery();

  89. FullTextQuery query = fullTextSession.createFullTextQuery(luceneQuery, Question.class);

  90. list=query.setMaxResults(2).list();

  91. JSONArray array=new JSONArray();

  92. for(Question question:list){

  93. array.add(packSearchQuestion(question,luceneQuery,str));

  94. }

  95.  
  96. return array;

  97. }

  98.  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值