繁体   English   中英

如何在休眠Lucene搜索中使用投影

[英]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;

Hibernate Search文档中所述

投影不适用于通过@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 ...)。 如果删除@IndexedEmbeddedJobSeeker.jobSeekerSkills ,那么你也可以去掉includePaths的新@IndexedEmbedded

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM