[英]How to use projections with hibernate lucene search
我正在进行休眠lucene搜索,可以很好地获取整个域对象。但是我的要求是投影。它只能在OneToMany关联字段上获取单个值,因此如何获取带有投影的@IndexedEmbedded字段的所有值。请协助您建议。 以下代码段是我的代码
@Indexed(index="Skills")
@AnalyzerDef(name = "skillAnalyzer",
tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
filters = {
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = SnowballPorterFilterFactory.class, params = {
@Parameter(name = "language", value = "English")
})
})
@Entity
@Table(name = "skills")
public class Skills {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "skill_id")
@Field(name="skillIdPk",index=Index.YES, analyze=Analyze.YES, store=Store.YES)
private int skillId;
@Field(index=Index.YES, analyze=Analyze.YES, store=Store.YES)
@Column(name = "skill")
private String skill;
@Column(name = "skill_type")
private String skillType = "default";
//setters & getters
}
@Indexed(index = "JobSeeker")
@AnalyzerDef(name = "jobSeekerAnalyzer", tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class), filters = {
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = SnowballPorterFilterFactory.class, params = {
@Parameter(name = "language", value = "English") }) })
@Entity
@Table(name = "jobseeker")
@Component
public class JobSeeker {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "jobseeker_id")
private long jobSeekerId;
@Column(name = "email_id", unique = true)
private String emailId;
@Column(name = "first_name")
private String firstName;
@Column(name = "middle_name")
private String middleName;
@Column(name = "last_name")
private String lastName;
@Column(name = "password")
private String password;
@IndexedEmbedded
private Set<JobSeekerSkills> jobSeekerSkills = new HashSet<JobSeekerSkills>();
//setters & getters
}
@Indexed(index="JobSeekerSkills")
@AnalyzerDef(name = "jobseekerSkillAnalyzer",
tokenizer = @TokenizerDef(factory=StandardTokenizerFactory.class),
filters = {
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = SnowballPorterFilterFactory.class, params = {
@Parameter(name = "language", value = "English")
})
})
@Entity
@Table(name="jobseeker_skills")
public class JobSeekerSkills
{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="jobseeker_skill_id")
private long jobSeekerSkillId;
@ManyToOne
@JoinColumn(name="jobseeker_jobseeker_id")
private JobSeeker jobSeeker;
@ManyToOne
@JoinColumn(name="skills_skill_id")
@IndexedEmbedded
private Skills skills;
//setters & getters
}
//=======================================================================
//This is my Dao code
FullTextSession fullTextSession = Search.getFullTextSession(session);
fullTextSession.createIndexer().startAndWait();
QueryBuilder qb = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(JobSeeker.class).get();
Query query = null;
for (String string : skills) {
query = qb.keyword().onField("jobSeekerSkills.skills.skillIdPk").matching(Integer.parseInt(string)).createQuery();
}
org.hibernate.search.FullTextQuery query1 =
fullTextSession.createFullTextQuery(query, JobSeeker.class);
query1.setProjection("jobSeekerId", "jobSeekerSkills.skills.skill");
List results = query1.list();
for (int i = 0; i < results.size(); i++) {
Object[] object = (Object[]) results.get(i);
System.out.println(object[0]);
System.out.println(object[1]);
}
// List<Skills> authorName1 = (List<Skills>) firstResult[1];
// System.out.println(authorName1);
return results;
投影不适用于通过@IndexedEmbedded索引的集合或地图
因此,在您的情况下,尝试对jobSeekerSkills.skills.skill
进行jobSeekerSkills.skills.skill
,将jobSeekerSkills
作为通过@IndexedEmbedded
索引的集合,不是一个好主意。
我想指出的是,由于您只在数字字段上执行关键字查询,因此最好只使用Hibernate ORM进行经典的JQPL / SQL查询。
无论如何,如果出于某种原因您真的想使用Hibernate Search,那么从查询中判断,您无需在集合上进行投影。 相反,只需添加一个@IndexedEmbedded(includePaths = "includePaths")
向jobSeeker
财产JobSeekerSkills
,然后返工您的查询的目标为实体索引JobSeekerSkills
:
FullTextSession fullTextSession = Search.getFullTextSession(session);
fullTextSession.createIndexer().startAndWait();
QueryBuilder qb = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(JobSeeker.class).get();
Query query = null;
for (String string : skills) {
query = qb.keyword().onField("skills.skillIdPk").matching(Integer.parseInt(string)).createQuery();
}
org.hibernate.search.FullTextQuery query1 =
fullTextSession.createFullTextQuery(query, JobSeeker.class);
query1.setProjection("jobSeeker.jobSeekerId", "skills.skill");
List results = query1.list();
for (int i = 0; i < results.size(); i++) {
Object[] object = (Object[]) results.get(i);
System.out.println(object[0]);
System.out.println(object[1]);
}
// List<Skills> authorName1 = (List<Skills>) firstResult[1];
// System.out.println(authorName1);
return results;
注: includePaths
在新@IndexedEmbedded
仅仅是必要的,因为你已经有一个@IndexedEmbedded
对联想(的反面JobSeeker.jobSeekerSkills
); 它避免了无限递归(JobSeeker.jobSeekerSkills.jobSeeker.jobSeekerSkills.jobSeeker.jobSeekerSkills ...)。 如果删除@IndexedEmbedded
上JobSeeker.jobSeekerSkills
,那么你也可以去掉includePaths
的新@IndexedEmbedded
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.