【问题标题】:Can you sort and search on same field with Hibernate/Lucene?你能用 Hibernate/Lucene 在同一个字段上排序和搜索吗?
【发布时间】:2013-08-12 19:41:31
【问题描述】:

我有以下带注释的类,我试图对来自 lucene/hibernate 搜索查询的结果进行排序。我终于让查询正常工作,但似乎当我实现必要的注释(在 jobStatus 上看到)来对该列进行排序时,就不可能再搜索该列。我的依据是我找到的说明 here on google。我一直在解决整个休眠搜索和排序问题,现在我终于弄清楚了如何排序和搜索,我所需要的就是能够一起完成它们。

@Entity
@Table(name="jobReq")
@Indexed
public class JobReq {

@Id
@DocumentId
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;

@Field(index = Index.YES)
@Column(name="jobId", nullable=false, unique=true)
private String jobId;

@Field(index = Index.YES)
@Column(name="jobTitle", nullable=false)
private String jobTitle;

@Field(index = Index.YES)
@Column(name="jobContract", nullable=false)
private String contract;

@Field(index = Index.YES)
@Column(name="jobProject", nullable=true)
private String project;

@Field(index = Index.YES)
@Column(name="jobLaborCategory", nullable=false)
private String laborCategory;

@Field(index = Index.YES)
@Column(name="jobSummary", nullable=false)
private String summary;

@Field(index = Index.YES)
@Column(name="jobDescription", nullable=false)
private String jobDescription;

@Fields({@Field, @Field(analyze  = Analyze.NO, name = "jobStatus")})
@Column(name="jobStatus", nullable=false)
private String status;

@Field(index = Index.YES)
@Column(name="TTONumber", nullable=false)
private String TTONumber;

@Field(index = Index.YES)
@Column(name="jobPostedDate", nullable=false)
@Type(type="date")
private Date postedDate;

还有一个来自搜索功能的sn-p

Field[] allFields = this.type.getDeclaredFields();
SortField field =new SortField(sortColumn, SortField.STRING, reverseSort);
Sort sort = new Sort(field);
hibQuery = fullTextSession.createFullTextQuery(bq, this.type).setSort(sort);
results = hibQuery.list();

【问题讨论】:

    标签: java hibernate sorting lucene hibernate-search


    【解决方案1】:

    Hibernate 搜索文档提供了一个类似于 Adam 的解决方案的解决方案。

    https://docs.jboss.org/hibernate/search/5.11/reference/en-US/html_single/#fields-annotation

    基本上使用两个@Field注解来索引一个字段,一次用Analyze.NO进行排序,一次用Analyze.YES进行搜索。

    @Entity
    @Indexed(index = "Book")
    public class Book {
    
        @Field
        @Field(name = "summary_forSort", analyze = Analyze.NO, store = Store.YES)
        @SortableField(forField = "summary_forSort")
        public String getSummary() {
            return summary;
        }
    
        // ...
    }
    

    analyze:确定属性是否被分析(Analyze.YES)或不被分析(Analyze.NO)。默认值为Analyze.YES。

    提示
    您是否要分析属性取决于您是要按原样搜索元素,还是要搜索它包含的单词。分析文本字段是有意义的,但可能不是日期字段。

    提示
    不得分析用于排序或分面的字段。

    【讨论】:

      【解决方案2】:

      事实证明,您无法在同一字段上进行排序和搜索,hibernate 书中的那篇文章有点误导。因此,我在休眠论坛上找到了a solution 的修复,因为您创建了一个重复的“影子”列,一个被注释用于搜索,而另一个被注释用于排序。

      我花了一段时间才找到这个解决方案,主要是因为答案似乎有点“hack-y”,虽然相当直接和简单,但在我的训练中,复制数据一直是一个禁忌。不过话说回来,我猜你每天都会学到一些新东西。

      【讨论】:

        【解决方案3】:

        两件事:

        1. 在每一列上创建索引可能会损害性能,因为索引更新不是免费的。它还可以使用不必要的额外存储空间。当然,如果这对您来说实际上不是瓶颈,那也没关系。

        2. 您可以使用 Hibernate Criteria 进行排序,例如:

          Criteria c = session.createCriteria(MyObject.class).addOrder(Order.desc(sortColumn));
          Query q = session.createFullTextQuery(bq).setCriteriaQuery(c);
          

          排序键列不需要索引。

        【讨论】:

        • 太棒了,谢谢。两个问题,我实际上还有其他字段(不想列出所有不必要的字段)所以如果我不对它们进行排序或搜索,最好的做法是不要索引它们?另外,如果我想做一个自定义排序标准(即在“关闭”之前排序“打开”,我可以用这种方法吗?
        • 我刚刚尝试过这种方法,我删除了 @Fields({@Field, @Field(analyze = Analyze.NO, name = "jobStatus")}) 并仅将其替换为 @Field() 并尝试根据“jobStatus”和“status”列对其进行排序。它没有排序,我不确定是不是因为变量名是'status'而数据库中的列名是'jobStatus'
        • 我必须道歉,并停止在这里回答,因为我不是 100% 熟悉 Hibernate Search,我想我最终只会给你错误信息。我没有意识到 Search 使用自己的索引方案。因此,我上面的第 1 点是无效的。我指的是数据库级别的索引。在研究 Hibernate Search 时,确实需要告诉 Search 索引字段,而 Search 使用自己的索引格式。我也可能错了,但我不建议遵循我之前的建议:索引。很抱歉让你走错了路。
        • 也就是说,仍然存在的那部分,以及上面问题的答案是,如果您不在字段上搜索/排序,不,您不应该创建索引在它上面-您将在生成索引时牺牲性能而没有任何收益,因为您从不使用它们。如果您更改了可搜索的字段,您可以随时添加索引。 有一点是,如果你想搜索/排序,你必须创建一个索引。
        • 不,您不能使用 Hibernate Criteria 实现自定义搜索条件。条件排序仅限于您可以使用 SQL ORDER BY 执行的操作。 Criteria 系统本质上为您提供了一种以编程方式构建 HQL 查询的简洁方法(而不是显式构建查询字符串)。对于基于业务价值的排序,您必须通过使用自定义Comparator 对对象集合进行排序来在业务逻辑中进行排序。或者,您可以分别选择 OpenClosed 项目并将两个列表连接起来,如果这更适合您的话。
        猜你喜欢
        • 1970-01-01
        • 2012-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-28
        • 1970-01-01
        相关资源
        最近更新 更多