[关闭]
@big-bear 2016-02-25T17:20:20.000000Z 字数 12403 阅读 1255

hibernate search

hibernate


原文链接

排序(sorting)

默认情况下,查询结果应该按照其和查询条件间的相关度进行排序。关于相关度排序,会在后续的文章中介绍。
但是我们也能够不再使用相关度作为排序的依据,转而我们可以使用日期,数值类型甚至字符串的顺序作为排序依据。比如,对App的搜索结果,我们可以使用其名字在字母表中的顺序进行排序。
为了支持对于某个域的排序,我们需要向索引中添加一些必要的信息。在对字符串类型的域进行索引时,默认的分析器会将该域的值进行分词,所以对于某个值“Hello World”,在索引中会有两个入口对“Hello”和“World”进行单独保存。这样做能够让查询更具效率,但是当我们需要对该域进行排序时,分词器是不需要的。

因此,我们可以对该域设置两个@Field注解:

  1. @Column
  2. @Fields({
  3. @Field,
  4. @Field(name="sorting_name", analyze=Analyze.NO)
  5. })
  6. private String name;

一个用来建立标准的索引,一个用来建立用于排序的索引,其中指定了analyze=Analyze.NO,默认情况下分词器是被使用的。

这个域就可以被用来创建Lucene的SortField对象,并集合FullTextQuery使用:

  1. import org.apache.lucene.search.Sort;
  2. import org.apache.lucene.search.SortField;
  3. // ...
  4. Sort sort = new Sort(new SortField("sorting_name", SortField.STRING));
  5. hibernateQuery.setSort(sort); // a FullTextQuery object

执行此查询后,得到的结果会按照App名字,从A-Z进行排序。 实际上,SortField还能够接受第三个boolean类型的参数,当传入true时,排序结果会被颠倒即从Z-A。

多条件查询

  1. public Query BuildQuery(Class<?> type, String category, String degree, String city, String keyWords, Long domainId,
  2. String[] fileds) {
  3. FullTextSession fullTextSession = Search.getFullTextSession(this.gqFactory.getSession());
  4. QueryBuilder qb = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(type).get();
  5. org.apache.lucene.search.Query luceneQuery = null;
  6. MustJunction term = qb.bool().must(qb.keyword().onFields(fileds).matching(keyWords).createQuery());
  7. if (StringUtils.isNotBlank(city)) {
  8. term.must(qb.keyword().onField("location").matching(city).createQuery());
  9. }
  10. if (StringUtils.isNotBlank(degree)) {
  11. term.must(qb.keyword().onField("degree").matching(degree).createQuery());
  12. }
  13. if (StringUtils.isNotBlank(category)) {
  14. term.must(qb.keyword().onField("category").matching(category).createQuery());
  15. }
  16. luceneQuery = term.createQuery();
  17. System.out.println(luceneQuery.toString());
  18. FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(luceneQuery, type);
  19. return fullTextQuery;
  20. }

多表联查

代码参考
注解的解释

实现的测试代码:
实体1:

  1. package com.wisdombud.wisdomhr.pojo.job;
  2. import java.util.Date;
  3. import java.util.Set;
  4. import javax.persistence.Column;
  5. import javax.persistence.Entity;
  6. import javax.persistence.JoinColumn;
  7. import javax.persistence.JoinTable;
  8. import javax.persistence.ManyToMany;
  9. import javax.persistence.Table;
  10. import javax.persistence.Temporal;
  11. import javax.persistence.TemporalType;
  12. import org.hibernate.search.annotations.Field;
  13. import org.hibernate.search.annotations.Fields;
  14. import org.hibernate.search.annotations.Index;
  15. import org.hibernate.search.annotations.Indexed;
  16. import org.hibernate.search.annotations.IndexedEmbedded;
  17. import org.hibernate.search.annotations.Store;
  18. import org.springframework.format.annotation.DateTimeFormat;
  19. import com.fasterxml.jackson.annotation.JsonFormat;
  20. import com.wisdombud.constants.Constants;
  21. import com.wisdombud.wisdomhr.pojo.dic.DicJoBDomain;
  22. /**
  23. * 功能: 职位表.<br/>
  24. * date: 2015年08月09日 10:59 <br/>
  25. *
  26. * @author joseph
  27. * @version
  28. */
  29. /**
  30. * @author wgzuo
  31. */
  32. @Entity
  33. @Table(name = "BASE_JOB")
  34. @Indexed(index = "indexes/job")
  35. public class BaseJob extends com.wisdombud.pojo.UuidEntity {
  36. private static final long serialVersionUID = 1L;
  37. @Column(name = "CARRER_ID")
  38. private String carrerId;
  39. @Column(name = "SPIDER_JOB_ID")
  40. private String spiderJobId;
  41. /**
  42. * 标题
  43. **/
  44. @Column(name = "TITLE")
  45. @Field(name = "title", index = Index.TOKENIZED, store = Store.YES)
  46. private String title;
  47. /**
  48. * 1:全职2:实习
  49. **/
  50. @Column(name = "CATEGORY")
  51. @Field(name = "category", index = Index.TOKENIZED, store = Store.YES)
  52. private String category;
  53. /**
  54. * 就业系统中的ID
  55. */
  56. @Column(name = "ENTERPRISE_CARRER_ID")
  57. private String enterpriseCarrerId;
  58. /**
  59. * 企业ID,如果有该ID 表示该职位是由企业发的
  60. **/
  61. @Column(name = "ENTERPRISE_ID")
  62. private String enterpriseId;
  63. /**
  64. * 企业名称
  65. **/
  66. @Column(name = "ENTERPRISE_NAME")
  67. @Field(name = "enterpriseName", index = Index.TOKENIZED, store = Store.YES)
  68. private String enterpriseName;
  69. @Column(name = "ENTERPRISE_LOGO")
  70. private String enterpriseLogo = Constants.ENTERPRISE_DEFAULT_PORTAIT; ;// 默认的logo;
  71. /**
  72. * 企业所属行业
  73. **/
  74. @Column(name = "ENTERPRISE_INDUSTRY")
  75. private String enterpriseIndustry;
  76. /**
  77. * 企业性质
  78. **/
  79. @Column(name = "ENTERPRISE_NATURE")
  80. private String enterpriseNature;
  81. /**
  82. * 工作城市,
  83. **/
  84. @Column(name = "LOCATION")
  85. @Field(name = "location", index = Index.TOKENIZED, store = Store.YES)
  86. private String location;
  87. /**
  88. * 学历要求,以“,”分隔的学历id1:大专及以上2:本科及以上3:硕士及以上4:博士
  89. **/
  90. @Field(name = "degree", index = Index.TOKENIZED, store = Store.YES)
  91. @Column(name = "DEGREE")
  92. private String degree;
  93. /**
  94. * 工资
  95. **/
  96. @Column(name = "SALARY")
  97. private String salary;
  98. /**
  99. * 阅读次数
  100. **/
  101. @Column(name = "VIEW_COUNT")
  102. private Integer viewCount = 0;
  103. @Column(name = "DELIVER_COUNT")
  104. private Integer deliverCount = 0;
  105. /**
  106. * 收藏次数
  107. **/
  108. @Column(name = "FAVORITE_COUNT")
  109. private Integer favoriteCount = 0;
  110. /**
  111. * 点赞数量
  112. **/
  113. @Column(name = "LIKE_COUNT")
  114. private Integer likeCount = 0;
  115. /**
  116. * 投递简历数量
  117. **/
  118. @Column(name = "RESUME_COUNT")
  119. private Integer resumeCount = 0;
  120. /**
  121. * 详细工作地址
  122. **/
  123. @Column(name = "ADDRESS")
  124. @Field(name = "address", index = Index.TOKENIZED, store = Store.YES)
  125. private String address;
  126. /**
  127. * hotWeight:热门排行权重.
  128. *
  129. * @since JDK 1.8
  130. */
  131. @Fields({ @Field, @Field(name = "hotWeight", index = Index.UN_TOKENIZED) })
  132. @Column(name = "HOT_WEIGHT")
  133. private Long hotWeight;
  134. /**
  135. * spreadLevel:推广级别,0是没有推广,1是最低级别
  136. *
  137. * @since JDK 1.8
  138. */
  139. @Column(name = "SPREAD_LEVEL")
  140. private Integer spreadLevel = 0;
  141. /**
  142. * invitationLevel:邀约级别,0是没有邀约,1是最低级别
  143. *
  144. * @since JDK 1.8
  145. */
  146. @Column(name = "INVITATION_LEVEL")
  147. private Integer invitationLevel = 0;
  148. /**
  149. * 0:无效1:有效2:举报处理中
  150. **/
  151. @Column(name = "STATUS")
  152. private Integer status = 1;
  153. /**
  154. * 举报ID
  155. **/
  156. @Column(name = "ACCUSATION_ID")
  157. private String accusationId;
  158. /**
  159. * 来源
  160. **/
  161. @Column(name = "SOURCE")
  162. private String source;
  163. @javax.persistence.Transient
  164. private String content;
  165. /**
  166. * 下线时间
  167. **/
  168. @JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")
  169. @DateTimeFormat(pattern = "yyyy-MM-dd")
  170. @Temporal(TemporalType.TIMESTAMP)
  171. @Column(name = "OFFLINE_TIME")
  172. protected Date offLineTime;
  173. /**
  174. * 激活时间
  175. **/
  176. @JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")
  177. @DateTimeFormat(pattern = "yyyy-MM-dd")
  178. @Temporal(TemporalType.TIMESTAMP)
  179. @Column(name = "ACTIVATE_TIME")
  180. protected Date activateTime;
  181. /**
  182. * 是否加V 0不加V 1加V
  183. **/
  184. @javax.persistence.Transient
  185. private Integer isVerify;
  186. /**
  187. * 是否有圈子的标记
  188. */
  189. // @Field(name = "domainId", index = Index.UN_TOKENIZED, store = Store.YES)
  190. @Column(name = "HAS_DOMAIN")
  191. private Integer hasDomain = 0;
  192. @ManyToMany
  193. @JoinTable(name = "H_REL_JOB_DOMAIN", joinColumns = { @JoinColumn(name = "JOB_ID") }, inverseJoinColumns = { @JoinColumn(name = "DOMAIN_ID") })
  194. @IndexedEmbedded
  195. private Set<DicJoBDomain> domains;
  196. public String getCarrerId() {
  197. return carrerId;
  198. }
  199. public void setCarrerId(String carrerId) {
  200. this.carrerId = carrerId;
  201. }
  202. public String getTitle() {
  203. return title;
  204. }
  205. public void setTitle(String title) {
  206. this.title = title;
  207. }
  208. public String getCategory() {
  209. return category;
  210. }
  211. public void setCategory(String category) {
  212. this.category = category;
  213. }
  214. public String getEnterpriseCarrerId() {
  215. return enterpriseCarrerId;
  216. }
  217. public void setEnterpriseCarrerId(String enterpriseCarrerId) {
  218. this.enterpriseCarrerId = enterpriseCarrerId;
  219. }
  220. public String getEnterpriseId() {
  221. return enterpriseId;
  222. }
  223. public void setEnterpriseId(String enterpriseId) {
  224. this.enterpriseId = enterpriseId;
  225. }
  226. public String getEnterpriseName() {
  227. return enterpriseName;
  228. }
  229. public void setEnterpriseName(String enterpriseName) {
  230. this.enterpriseName = enterpriseName;
  231. }
  232. public String getEnterpriseIndustry() {
  233. return enterpriseIndustry;
  234. }
  235. public void setEnterpriseIndustry(String enterpriseIndustry) {
  236. this.enterpriseIndustry = enterpriseIndustry;
  237. }
  238. public String getEnterpriseNature() {
  239. return enterpriseNature;
  240. }
  241. public void setEnterpriseNature(String enterpriseNature) {
  242. this.enterpriseNature = enterpriseNature;
  243. }
  244. public String getLocation() {
  245. return location;
  246. }
  247. public void setLocation(String location) {
  248. this.location = location;
  249. }
  250. public String getDegree() {
  251. return degree;
  252. }
  253. public void setDegree(String degree) {
  254. this.degree = degree;
  255. }
  256. public String getSalary() {
  257. return salary;
  258. }
  259. public void setSalary(String salary) {
  260. this.salary = salary;
  261. }
  262. public Integer getViewCount() {
  263. if (viewCount == null) {
  264. return 0;
  265. }
  266. return viewCount;
  267. }
  268. public void setViewCount(Integer viewCount) {
  269. this.viewCount = viewCount;
  270. }
  271. public Integer getFavoriteCount() {
  272. if (favoriteCount == null) {
  273. return 0;
  274. }
  275. return favoriteCount;
  276. }
  277. public void setFavoriteCount(Integer favoriteCount) {
  278. this.favoriteCount = favoriteCount;
  279. }
  280. public Integer getDeliverCount() {
  281. if (deliverCount == null) {
  282. return 0;
  283. }
  284. return deliverCount;
  285. }
  286. public void setDeliverCount(Integer deliverCount) {
  287. this.deliverCount = deliverCount;
  288. }
  289. public Integer getLikeCount() {
  290. if (likeCount == null) {
  291. return 0;
  292. }
  293. return likeCount;
  294. }
  295. public void setLikeCount(Integer likeCount) {
  296. this.likeCount = likeCount;
  297. }
  298. public Integer getResumeCount() {
  299. if (resumeCount == null) {
  300. return 0;
  301. }
  302. return resumeCount;
  303. }
  304. public void setResumeCount(Integer resumeCount) {
  305. this.resumeCount = resumeCount;
  306. }
  307. public String getAddress() {
  308. return address;
  309. }
  310. public void setAddress(String address) {
  311. this.address = address;
  312. }
  313. public Long getHotWeight() {
  314. if (hotWeight == null) {
  315. return 0L;
  316. }
  317. return hotWeight;
  318. }
  319. public void setHotWeight(Long hotWeight) {
  320. this.hotWeight = hotWeight;
  321. }
  322. public Integer getSpreadLevel() {
  323. return spreadLevel;
  324. }
  325. public void setSpreadLevel(Integer spreadLevel) {
  326. this.spreadLevel = spreadLevel;
  327. }
  328. public Integer getInvitationLevel() {
  329. return invitationLevel;
  330. }
  331. public void setInvitationLevel(Integer invitationLevel) {
  332. this.invitationLevel = invitationLevel;
  333. }
  334. public String getSource() {
  335. return source;
  336. }
  337. public void setSource(String source) {
  338. this.source = source;
  339. }
  340. public Integer getStatus() {
  341. return status;
  342. }
  343. public void setStatus(Integer status) {
  344. this.status = status;
  345. }
  346. public String getAccusationId() {
  347. return accusationId;
  348. }
  349. public void setAccusationId(String accusationId) {
  350. this.accusationId = accusationId;
  351. }
  352. public String getContent() {
  353. return content;
  354. }
  355. public void setContent(String content) {
  356. this.content = content;
  357. }
  358. public String getEnterpriseLogo() {
  359. return enterpriseLogo;
  360. }
  361. public void setEnterpriseLogo(String enterpriseLogo) {
  362. this.enterpriseLogo = enterpriseLogo;
  363. }
  364. public Date getOffLineTime() {
  365. return offLineTime;
  366. }
  367. public void setOffLineTime(Date offLineTime) {
  368. this.offLineTime = offLineTime;
  369. }
  370. public Date getActivateTime() {
  371. return activateTime;
  372. }
  373. public void setActivateTime(Date activateTime) {
  374. this.activateTime = activateTime;
  375. }
  376. /**
  377. * @see java.lang.Object#hashCode()
  378. */
  379. @Override
  380. public int hashCode() {
  381. final int prime = 31;
  382. int result = 1;
  383. result = prime * result + ((this.id == null) ? 0 : id.hashCode());
  384. return result;
  385. }
  386. /**
  387. * @see java.lang.Object#equals(java.lang.Object)
  388. */
  389. @Override
  390. public boolean equals(Object obj) {
  391. if (this == obj)
  392. return true;
  393. if (obj == null)
  394. return false;
  395. if (getClass() != obj.getClass())
  396. return false;
  397. BaseJob other = (BaseJob) obj;
  398. if (id == null) {
  399. if (other.id != null)
  400. return false;
  401. } else if (!id.equals(other.id))
  402. return false;
  403. return true;
  404. }
  405. public Integer getIsVerify() {
  406. return isVerify;
  407. }
  408. public String getSpiderJobId() {
  409. return spiderJobId;
  410. }
  411. public void setSpiderJobId(String spiderJobId) {
  412. this.spiderJobId = spiderJobId;
  413. }
  414. public void setIsVerify(Integer isVerify) {
  415. this.isVerify = isVerify;
  416. }
  417. public Integer getHasDomain() {
  418. return hasDomain;
  419. }
  420. public void setHasDomain(Integer hasDomain) {
  421. this.hasDomain = hasDomain;
  422. }
  423. public Set<DicJoBDomain> getDomains() {
  424. return domains;
  425. }
  426. public void setDomains(Set<DicJoBDomain> domains) {
  427. this.domains = domains;
  428. }
  429. }

实体2:

  1. /**
  2. * Copyright (c) 2015, www.wisdombud.com
  3. * All Rights Reserved.
  4. */
  5. package com.wisdombud.wisdomhr.pojo.dic;
  6. import java.util.Set;
  7. import javax.persistence.Column;
  8. import javax.persistence.Entity;
  9. import javax.persistence.Id;
  10. import javax.persistence.ManyToMany;
  11. import javax.persistence.Table;
  12. import com.wisdombud.wisdomhr.pojo.job.BaseJob;
  13. /**
  14. * 功能: 职位圈子实体.<br/>
  15. * date: 2015年12月21日 下午3:35:45 <br/>
  16. *
  17. * @author ytche@wisdombud.com
  18. * @version
  19. * @since JDK 1.8
  20. */
  21. @Entity
  22. @Table(name = "DIC_JOB_DOMAIN")
  23. public class DicJoBDomain {
  24. @Id
  25. private Long id;
  26. @Column(name = "NAME")
  27. private String name;
  28. @ManyToMany(mappedBy = "domains")
  29. private Set<BaseJob> baseJobs;
  30. public Long getId() {
  31. return id;
  32. }
  33. public void setId(Long id) {
  34. this.id = id;
  35. }
  36. public String getName() {
  37. return name;
  38. }
  39. public void setName(String name) {
  40. this.name = name;
  41. }
  42. public Set<BaseJob> getBaseJobs() {
  43. return baseJobs;
  44. }
  45. public void setBaseJobs(Set<BaseJob> baseJobs) {
  46. this.baseJobs = baseJobs;
  47. }
  48. }

srv方法:

  1. import org.apache.commons.lang.StringUtils;
  2. import org.hibernate.Query;
  3. import org.hibernate.search.FullTextQuery;
  4. import org.hibernate.search.FullTextSession;
  5. import org.hibernate.search.Search;
  6. import org.hibernate.search.query.dsl.MustJunction;
  7. import org.hibernate.search.query.dsl.QueryBuilder;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.stereotype.Service;
  10. import com.wisdombud.dao.GeneralQueryFactory;
  11. public Query testIndexedEmbedded(Class<?> type) {
  12. FullTextSession fullTextSession = Search.getFullTextSession(this.gqFactory.getSession());
  13. QueryBuilder qb = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(type).get();
  14. org.apache.lucene.search.Query luceneQuery = qb.keyword().onFields("domains.id").matching("1").createQuery();
  15. FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(luceneQuery, type);
  16. return fullTextQuery;
  17. }

test方法

  1. public class lianchaTest extends AbstractTransactionContextTest {
  2. @Autowired
  3. JobSearch jobSearch;
  4. @Test
  5. public void test() {
  6. Query query = this.jobSearch.testIndexedEmbedded(BaseJob.class);
  7. List<BaseJob> baseJobs = query.list();
  8. System.out.println(baseJobs.size() + "--------");
  9. }
  10. }

一个hibernate search配置相关的东西

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注