2017-04-12 33 views
0

我正在做hibernate lucene搜索。它与获得整个域对象工作正常。但我的要求是预测。它只获得OneToMany关联域的单一值。所以我怎么能得到所有@IndexedEmbedded字段的值与projection.Please协助您的建议。 下面的片段是我的代码如何使用预测与休眠lucene搜索

@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; 

回答

2

正如提到的Hibernate Search documentation

投影不会在集合或映射工作,这是你的情况通过@IndexedEmbedded

所以索引,试图在jobSeekerSkills.skills.skill上投影,jobSeekerSkills是通过@IndexedEmbedded索引的集合,这不是一个好主意。

我想指出的是,由于您只是在数值字段上执行关键字查询,因此使用Hibernate ORM执行经典的JQPL/SQL查询可能会更好。

无论如何,如果由于某种原因您确实想要使用Hibernate Search进行此操作,从您的查询来看,您不需要在集合上进行投影。相反,只需添加一个@IndexedEmbedded(includePaths = "includePaths")JobSeekerSkillsjobSeeker属性,然后返工查询目标为实体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 ...)。如果您删除JobSeeker.jobSeekerSkills上的@IndexedEmbedded,则还可以删除新的@IndexedEmbedded上的includePaths

+0

我解决了上面的问题。但现在我也遇到了同样的错误,就像我在帖子中提到的那样。我没有找到求职者所有的技能,它只为每位求职者提供单一技能。即使与多种技能相关联,它也会像one-to-one一样提供单一记录。是否有任何方法可以使用Hibernate lucene投影获取所有Indexembedded实体的值? –

+0

不,您不能拥有包含求职者ID和全文查询结果的技能集合的元组列表。你可以得到的最好的是包含求职者ID和其技能之一的元组列表,然后你必须发布这个过程来按求职者ID对技能进行分组。如果这不是你想要的,就像我上面所说的那样,你最好使用简单的JPQL/HQL查询,因为在这种情况下你不需要全文搜索。 –