如何在复杂类型上订购Hibernate搜索结果

时间:2018-03-29 10:09:09

标签: java hibernate lucene hibernate-search

我想基于licensePlate模糊搜索所有车辆,并在fleetCustomer.customerId之后订购。

到目前为止,我可以进行模糊搜索,但在我拥有的时候,它似乎很难自己完成。

hibernate-search库的版本是5.5.5.final

我有两个实体:

车辆:

@Entity
@Table(name = "VEHICLE")
@Indexed
public class VehicleDao {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "vehicle_id")
    private Long vehicleId;

    @Column(name = "license_plate", length = 50)
    @Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO)
    private String licensePlate;

    @IndexedEmbedded
    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "fleetCustomer")
    @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
    private CustomerDao fleetCustomer;

    ...
}

和客户:

@Embeddable
@Entity
@Table(name="CUSTOMER")
public class CustomerDao {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "CUSTOMER_ID", nullable = false)
    private Long customerId;

...

}

到目前为止,我尝试将排序属性作为字段添加到搜索中,但这不起作用,不会返回任何结果。

这是我到目前为止所尝试的,模糊搜索正在运行。 从代码中可以看出具有fleetCustomer.customerId = 1025的车辆必须是第一个。

        org.apache.lucene.search.Query luceneQuery = b.bool()
                .must( b.keyword().fuzzy().onField("licensePlate").boostedTo(3)
                        .matching("mhp 070").createQuery() )
//        .must( b.keyword().onField("fleetCustomer.customerId").ignoreFieldBridge()
//                .matching("1025").createQuery() )
                .createQuery();

        final org.hibernate.search.jpa.FullTextQuery fullTextQuery =
                fullTextEntityManager.createFullTextQuery( luceneQuery , VehicleDao.class);

        fullTextQuery.setFirstResult(1);
        fullTextQuery.setMaxResults(5);

        List<T> resultList = fullTextQuery.getResultList();

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

如果您想订购结果,则不应更改查询。你应该添加一种排序。

编辑:我没有看到您使用的是Search 5.5。这是Search 5.5的解决方案。顺便提一下,这个版本已经老了,你应该考虑升级。

添加一个字段以对客户ID进行排序:

@Embeddable
@Entity
@Table(name="CUSTOMER")
public class CustomerDao {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "CUSTOMER_ID", nullable = false)
    @Field(name = "customerId_sort") // <== Add this
    @SortableField(forField = "customerId_sort")  // <== And this
    private Long customerId;

...

}

然后在查询时添加一个排序:

        org.apache.lucene.search.Query luceneQuery = b.bool()
                .must( b.keyword().fuzzy().onField("licensePlate").boostedTo(3)
                        .matching("mhp 070").createQuery() )
                .createQuery();

        final org.hibernate.search.jpa.FullTextQuery fullTextQuery =
                fullTextEntityManager.createFullTextQuery( luceneQuery , VehicleDao.class);


        // Add this
        org.apache.lucene.search.Sort sort = new org.apache.lucene.search.Sort( new org.apache.lucene.search.SortField( "fleetCustomer.customerId_sort", org.apache.lucene.search.SortField.Type.LONG ) )
        fullTextQuery.setSort( sort );

        fullTextQuery.setFirstResult(1);
        fullTextQuery.setMaxResults(5);

        List<T> resultList = fullTextQuery.getResultList();

如果您不熟悉Hibernate Search,特别是如果您还是全文新手,我建议您查看the section about sorts in the Hibernate Search documentation

原始解决方案(适用于Search 5.6及更高版本):

添加一个字段以对客户ID进行排序:

@Embeddable
@Entity
@Table(name="CUSTOMER")
public class CustomerDao {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "CUSTOMER_ID", nullable = false)
    @Field(name = "customerId_sort") // <== Add this
    @SortableField(forField = "customerId_sort")  // <== And this
    private Long customerId;

...

}

然后在查询时添加一个排序:

        org.apache.lucene.search.Query luceneQuery = b.bool()
                .must( b.keyword().fuzzy().onField("licensePlate").boostedTo(3)
                        .matching("mhp 070").createQuery() )
                .createQuery();

        final org.hibernate.search.jpa.FullTextQuery fullTextQuery =
                fullTextEntityManager.createFullTextQuery( luceneQuery , VehicleDao.class);


        // Add this
        org.apache.lucene.search.Sort sort = b.sort().byField( "fleetCustomer.customerId_sort" ).createSort();
        fullTextQuery.setSort(sort);

        fullTextQuery.setFirstResult(1);
        fullTextQuery.setMaxResults(5);

        List<T> resultList = fullTextQuery.getResultList();

如果您不熟悉Hibernate Search,特别是如果您还是全文新手,我建议您查看the section about sorts in the Hibernate Search documentation