2017-04-12 32 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查詢,因爲在這種情況下你不需要全文搜索。 –