嵌入式实体上的Hibernate过滤器

时间:2018-06-02 20:51:52

标签: java hibernate full-text-search dropwizard

我有一个使用hibernate搜索的Dropwizard应用程序。简而言之,我在我的数据库中有动物及其数据,我正在尝试添加过滤器以获取特定品种列表的动物。不幸的是,似乎我的过滤器不起作用,我无法弄清楚原因。我怀疑可能是我如何定义我的实体之间的关系以及我如何尝试引用A: [-115, 44, -24, 125, -122, -11, 95, -49, -85, 119, 10, 4, 123, 9, 13, -94, 50, 112, -6, 32, 104, 50, -33, -22, 126, 12, -108, 111, -1, 69, 31, -127, -102, -35, 36, 35, 116, -66, 85, 27, 13, 99, 24, -19, 108, 125, 65, -40] B: [49, 123, -48, 9, 32, 59, -57, -101, 6, 78, 83, -8, -20, -53, 99, 46, 5, 19, -121, 44, -98, -59, -64, -90, -108, -106, -82, -8, -106, 113, -81, 33, -19, -110, -93, -78, 85, 72, 12, 90, 9, 118, -22, 73, 37, -118, -64, -114] C: [49, 123, -48, 9, 32, 59, -57, -101, 6, 78, 83, -8, -20, -53, 99, 46, 5, 19, -121, 44, -98, -59, -64, -90, -108, -106, -82, -8, -106, 113, -81, 33, -19, -110, -93, -78, 85, 72, 12, 90, 9, 118, -22, 73, 37, -118, -64, -114] 中的品种属性,但它似乎对我而言。我已根据Hibernate documentation实施了我的过滤器。相关课程如下:

我的FilterFactory课程:

Animal

我的@Entity @Indexed @FullTextFilterDef(name = "animalFilter", impl = AnimalFilterFactory.class) @Table(name = "animal") @JsonIgnoreProperties(ignoreUnknown = true) public class Animal implements Serializable{ @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @IndexedEmbedded @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "animal") private AnimalInfo info; // rest of the class goes here } 课程:

AnimalInfo

我的@Entity @Table(name = "animal_info") @JsonIgnoreProperties(ignoreUnknown = true) public class AnimalInfo implements Serializable{ @Id @Column(name = "animal_id") private Long animalId; @IndexedEmbedded @ManyToOne( cascade = CascadeType.ALL ) @JoinColumn(name="breed_id") private AnimalBreed breed; // rest of the class goes here } 课程:

AnimalBreed

我的过滤器类:也许@Entity @Table(name = "animal_breeds") @JsonIgnoreProperties(ignoreUnknown = true) public class AnimalBreed implements Serializable{ @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; /** * name of the breed which I want to filter my animals on. */ @Field @Column(name = "name") private String name; 语句不正确?

"info.breed.name"

在我想要应用过滤器的DAO类中:

public class AnimalFilterFactory {
    // list of breed names
    private List<String> breeds;

    public void setBreeds(List<String> breeds) {
        this.breeds = breeds;
    }    
    @Factory
    public Query getFilter() {

        BooleanQuery.Builder booleanQuery = new BooleanQuery.Builder();
         // apply filter for all the breeds
        for (String breed : breeds) {
            booleanQuery.add(new TermQuery( new Term( "info.breed.name", breed ) ), Occur.SHOULD);
        }
        return booleanQuery.build();
    }

}

我已经测试过,在不应用过滤器的情况下,我的DB中的所有Animal实体都会被返回。所以似乎过滤器绝对是个问题。

感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

事实证明,我的方法是正确的,我只是误解了Lucene如何对其术语进行索引。例如品种&#34; Boston Terrier&#34;被索引为&#34;波士顿&#34;和&#34;小猎犬&#34;。要过滤整个短语,必须使用PhraseQuery而不是TermQuery。我更新了我的过滤器,如下所示:

@Factory
    public Query getFilter() {

        BooleanQuery.Builder booleanQuery = new BooleanQuery.Builder();

        String fieldId = "info.breed.name";

        //booleanQuery.setMinimumNumberShouldMatch(1);
        for (String breed : breeds) {

            if(breed.contains(" ")) { // if multiple terms in breed
                PhraseQuery.Builder builder = new PhraseQuery.Builder();

                String[] terms = breed.split(" ");

                for (int i = 0; i < terms.length; i++) {
                    builder.add(new Term( fieldId, terms[i].toLowerCase() ), i);
                }

                PhraseQuery pq = builder.build();

                BooleanClause clause = new BooleanClause(pq, Occur.SHOULD);
                booleanQuery.add(clause);
            }else {
                // single term
                BooleanClause clause = new BooleanClause(new TermQuery( new Term(fieldId, breed.toLowerCase() ) ), Occur.SHOULD);
                booleanQuery.add(clause);
            }


        }

        BooleanQuery query = booleanQuery.build();
        return query;
    }

为了记录,我通过使用Luke检查索引实体字段并相应地调整我的代码来解决这个问题。只是确保为Lucene索引使用正确版本的Luke,因为版本不兼容。 Luke和Lucene版本彼此平行。就我而言,我使用的是5.5版。