java - Lucene 外部字段查询

标签 java spring hibernate lucene hibernate-search

我有这两个 pojo:

@Entity
@Table(name = "ITEM", uniqueConstraints = @UniqueConstraint(
        columnNames = {"ITEM_CODE", "ITEM_CODE_VERSION"}
))
@Indexed
@AnalyzerDef(name = "customAnalyzer", tokenizer = @TokenizerDef(factory =    LetterTokenizerFactory.class),
    filters = {
            @TokenFilterDef(factory = LowerCaseFilterFactory.class),
    })
public class Item implements Serializable {
@Field
private String brand;

@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator = "item_generator")
@SequenceGenerator(name = "item_generator",sequenceName = "ITEM_SEQ")
@Column(name = "ITEM_ID")
private Integer id;

@Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
@FieldBridge(impl = IntegerBridge.class)
@Column(name = "ITEM_CODE")
private Integer itemCode;

@Column(name = "ITEM_CODE_VERSION")
private Integer itemCodeVersion;

@Column(name="TXT_MODULE_NAME")
@Field
private String moduleName;

@OneToMany(mappedBy = "item", fetch= FetchType.EAGER)
@IndexedEmbedded
private Set<CriticalComponent> criticalComponents = new HashSet<>();

//getters and setters

@Entity
@Table(name = "CRITICAL_COMPONENT")
@Indexed
public class CriticalComponent implements Serializable {

@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator = "crit_comp_generator")
@SequenceGenerator(name = "crit_comp_generator",sequenceName = "CRIT_COMP_SEQ")
@Column(name = "CRITICAL_COMPONENT_ID")
private Integer id;

@ContainedIn
@ManyToOne
@JoinColumns(value = {
        @JoinColumn(name = "ITEM_CODE", referencedColumnName = "ITEM_CODE"),
        @JoinColumn(name = "ITEM_CODE_VERSION", referencedColumnName = "ITEM_CODE_VERSION")
})
private Item item;

@Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
@Column(name = "CRITICAL_FILENAME")
private String criticalFilename;

//getters and setters

我有从 Item OneToMany 到 CriticalComponent 的关系,我想构建一个 lucene 查询来通过 ItemCode 搜索 CriticalComponent(2nd pojo),ItemCode 是 Item 中的一个字段,但是当我从 View 中点击搜索按钮时,它会给出以下错误:

There was an unexpected error (type=Internal Server Error, status=500). Unable to find field itemCode in io.package.CriticalComponent.

这是 hibernate 搜索服务:

@Transactional
public List<CriticalComponent> searchForCriticalComponent(String     searchTerm){

    FullTextEntityManager fullTextEntityManager =     Search.getFullTextEntityManager(entityManager);
    QueryBuilder qb =   fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(CriticalComponent.class).get();
    //Query luceneQuery = qb.keyword().fuzzy().withEditDistanceUpTo(1).withPrefixLength(1).onFields("criticalFilename", "itemCode", "serviceName").matching(searchTerm).createQuery();
    Query luceneQuery = qb.keyword().wildcard().onFields("criticalFilename","itemCode").matching(searchTerm.toLowerCase()+'*').createQuery();

    javax.persistence.Query jpaQuery = fullTextEntityManager.createFullTextQuery(luceneQuery, CriticalComponent.class);

    List<CriticalComponent> criticalComponentsModel = null;
    try {
        criticalComponentsModel  = jpaQuery.getResultList();
    } catch (NoResultException nre) {
        log.debug("Search: No result found");
    }
    return criticalComponentsModel;
}

如何从关键组件类中按项目代码进行搜索?

最佳答案

我解决了。

这里的变化:

Item.java看起来一样,但它必须有@ContainedIn注释

@OneToMany(mappedBy = "item", fetch= FetchType.EAGER)
@ContainedIn
private Set<CriticalComponent> criticalComponents = new HashSet<>();

CriticalComponent.java 相同但必须有 @IndexEmbedded 注解

@IndexedEmbedded
@ManyToOne
@JoinColumns(value = {
        @JoinColumn(name = "ITEM_CODE", referencedColumnName = "ITEM_CODE"),
        @JoinColumn(name = "ITEM_CODE_VERSION", referencedColumnName = "ITEM_CODE_VERSION")
})
private Item item;

Hibernate 搜索服务查找通过点访问的关系字段:

@Transactional
public List<CriticalComponent> searchForCriticalComponent(String searchTerm){

    FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
    QueryBuilder qb = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(CriticalComponent.class).get();
    //Query luceneQuery = qb.keyword().fuzzy().withEditDistanceUpTo(1).withPrefixLength(1).onFields("criticalFilename", "itemCode", "serviceName").matching(searchTerm).createQuery();
    Query luceneQuery = qb.keyword().wildcard().onFields("criticalFilename","serviceName","item.itemCode").matching(searchTerm.toLowerCase()+'*').createQuery();

    javax.persistence.Query jpaQuery = fullTextEntityManager.createFullTextQuery(luceneQuery, CriticalComponent.class);

    List<CriticalComponent> criticalComponentsModel = null;
    try {
        criticalComponentsModel  = jpaQuery.getResultList();
    } catch (NoResultException nre) {
        log.debug("Search: No result found");
    }
    return criticalComponentsModel;
}

关于java - Lucene 外部字段查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47431151/

相关文章:

json - 如何测试 Spring Boot Controller 的错误输出?

java - 如何在 Hibernate native 查询中使用常量?

java - 在Java中将数值转换为日期

javascript - 是否可以通过 WebSocket 握手发送自定义数据?

java - 如何 Autowiring RedisTemplate<String,Long>

java - 从数据库 SQL oracle 保存和获取 blob 时出错

hibernate - 为什么我在使用 Hibernate 时会在简单的 "get"中收到错误?

java - Bootstrap 字形在 java webapp 中不起作用

java - J2ME Https 连接不工作

java - 从未调用过 Spring validator