今天我有一个非常奇怪的案例(对我来说:-))经过几个小时的搜索后,我没有找到任何答案。
我使用Spring和Hibernate构建了一个网站。我试图使用Hibernate搜索(Lucene)但没有成功,或者让我们说部分成功。
我的实体(inspectionMaster)配置了一些索引字段:
@Entity
@Indexed
@Table(name="LGIMAS")
public class InspectionMaster implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="LMISID", insertable=false, updatable=false)
private Long id;
@Column(name="LMRANK", nullable=false)
private Integer rank;
@Column(name="LMPIID", nullable=false)
private Long parentInspection;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="SITID")
@IndexedEmbedded
private Site site;
@Field(index=Index.YES, analyze=Analyze.YES, store=Store.YES)
@Column(name="LMVNDN", nullable=false, length=6)
private String vendorNr;
@Field(index=Index.YES, analyze=Analyze.YES, store=Store.YES)
@Column(name="LMVNNM", nullable=false, length=25)
private String vendorDesc;
@Field(index=Index.YES, analyze=Analyze.YES, store=Store.YES)
@Column(name="LMITEM", nullable=false, length=15)
private String itemNr;
@Field(index=Index.YES, analyze=Analyze.YES, store=Store.YES)
@Column(name="LMITDS", nullable=false, length=40)
private String itemDesc;
@Column(name="LMSTAT", nullable=false, length=2)
@Convert(converter = StatusConverter.class)
private StatusType status;
@Transient
private String statusDesc;
@Column(name="LMRMCT", nullable=false)
private Long remoteID;
@Column(name="LMPRTU", nullable=false, precision=1, scale=0)
private BigDecimal priorityUrg;
@Column(name="LMPRTC", nullable=false, precision=5, scale=0)
private BigDecimal priorityCust;
@Column(name="LMPRTD", nullable=false, precision=2, scale=0)
private BigDecimal priorityDate;
@Column(name="LMPRTE", nullable=false, precision=2, scale=0)
private BigDecimal priorityExt;
@Column(name="LMSTRL", nullable=false, length=1)
private String stockRelease;
@Column(name="LMUPDI", nullable=false, length=1)
private String updItem;
@Column(name="LMRCHK", nullable=false, length=1)
private String recheck;
@Column(name="LMRCHD")
private Timestamp recheckDate;
@Column(name="LMRFCP", nullable=false, length=1)
private String fullPackIDcontrol;
@Column(name="LMSPAC", nullable=false, length=2)
@Convert(converter = ActionsConverter.class)
private ActionsType specificAction;
@Column(name="LMTYPE", nullable=false, length=1)
private String requestType;
@Column(name="LMRCDT")
private Timestamp receptDate;
@Column(name="LMRCUS", length=25)
private String receptUser;
@Column(name="LMCTDT")
private Timestamp controlDate;
@Column(name="LMCTUS", length=25)
private String controlUser;
@Column(name="LMAPDT")
private Timestamp approvalDate;
@Column(name="LMAPUS", length=25)
private String approvalUser;
@Column(name="LMUNIT", nullable=false, precision=5, scale=0)
private BigDecimal unitByOuter;
@Column(name="LMOPCK", nullable=false, precision=5, scale=0)
private BigDecimal packID;
@Column(name="LMCFDD")
private Timestamp coFirstMDD;
@Column(name="LMCAMT", nullable=false, precision=13, scale=2)
private BigDecimal coAmount;
@Column(name="LMCADT")
private Timestamp customerAnalyseDate;
@Embedded
@Transient
private List<Whinv> whinv = new ArrayList<Whinv>();
@Field(index=Index.YES, analyze=Analyze.YES, store=Store.YES)
@Column(name="LMWPLC", nullable=false, length=10)
private String whmPickLocation;
@Transient
private boolean WHINVExist;
我用Luke检查我的Lucene索引,如果完全正确,则填写所需的单词......
我构建了一个JUnit测试用例:
@Test
public void B_testIndexes() {
// get the full text entity manager
FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search.getFullTextEntityManager(em);
// create the query using Hibernate Search query DSL
QueryBuilder queryBuilder = fullTextEntityManager
.getSearchFactory()
.buildQueryBuilder()
.forEntity(InspectionMaster.class)
.get();
// Build Query !
Query query1 = queryBuilder.keyword().wildcard().onField("site.siteId").matching("*lpb*").createQuery();
Query query2 = queryBuilder.keyword().wildcard().onField("site.sitedescription").matching("*france*").createQuery();
Query query3 = queryBuilder.keyword().wildcard().onField("vendorNr").matching("*s07610*").createQuery();
Query query4 = queryBuilder.keyword().wildcard().onField("vendorDesc").matching("*limited*").createQuery();
Query query5 = queryBuilder.keyword().wildcard().onField("itemNr").matching("*0023*").createQuery();
Query query6 = queryBuilder.keyword().wildcard().onField("itemDesc").matching("*28w*").createQuery();
Query query7 = queryBuilder.keyword().wildcard().onField("whmPickLocation").matching("*00*").createQuery();
Query query8 = queryBuilder
.bool()
.should( queryBuilder.keyword().wildcard().onField("site.siteId").matching("*lpb*").createQuery() )
.should( queryBuilder.keyword().wildcard().onField("site.sitedescription").matching("*france*").createQuery() )
.should( queryBuilder.keyword().wildcard().onField("vendorNr").matching("*s07610*").createQuery() )
.should( queryBuilder.keyword().wildcard().onField("vendorDesc").matching("*limited*").createQuery() )
.should( queryBuilder.keyword().wildcard().onField("itemNr").matching("*0023*").createQuery() )
.should( queryBuilder.keyword().wildcard().onField("itemDesc").matching("*28w*").createQuery() )
.should( queryBuilder.keyword().wildcard().onField("whmPickLocation").matching("*00*").createQuery() )
.createQuery();
Query query9 = queryBuilder
.bool()
.should( queryBuilder.keyword().wildcard().onField("site.siteId").matching("*lpb*").createQuery() )
.should( queryBuilder.keyword().wildcard().onField("site.sitedescription").matching("*lpb*").createQuery() )
.should( queryBuilder.keyword().wildcard().onField("vendorNr").matching("*lpb*").createQuery() )
.should( queryBuilder.keyword().wildcard().onField("vendorDesc").matching("*lpb*").createQuery() )
.should( queryBuilder.keyword().wildcard().onField("itemNr").matching("*lpb*").createQuery() )
.should( queryBuilder.keyword().wildcard().onField("itemDesc").matching("*lpb*").createQuery() )
.should( queryBuilder.keyword().wildcard().onField("whmPickLocation").matching("*lpb*").createQuery() )
.createQuery();
// wrap Lucene query in an Hibernate Query object
FullTextQuery jpaQuery = fullTextEntityManager.createFullTextQuery(query1, InspectionMaster.class);
logService.log("TEST : Test search on site.siteId = *lpb* return " + jpaQuery.getResultSize() + " documents");
jpaQuery = fullTextEntityManager.createFullTextQuery(query2, InspectionMaster.class);
logService.log("TEST : Test search on site.sitedescription = *france* return " + jpaQuery.getResultSize() + " documents");
jpaQuery = fullTextEntityManager.createFullTextQuery(query3, InspectionMaster.class);
logService.log("TEST : Test search on vendorNr = *s07610* return " + jpaQuery.getResultSize() + " documents");
jpaQuery = fullTextEntityManager.createFullTextQuery(query4, InspectionMaster.class);
logService.log("TEST : Test search on vendorDesc = *limited* return " + jpaQuery.getResultSize() + " documents");
jpaQuery = fullTextEntityManager.createFullTextQuery(query5, InspectionMaster.class);
logService.log("TEST : Test search on itemNr = *0023* return " + jpaQuery.getResultSize() + " documents");
jpaQuery = fullTextEntityManager.createFullTextQuery(query6, InspectionMaster.class);
logService.log("TEST : Test search on itemDesc = *28w* return " + jpaQuery.getResultSize() + " documents");
jpaQuery = fullTextEntityManager.createFullTextQuery(query7, InspectionMaster.class);
logService.log("TEST : Test search on whmPickLocation = *00* return " + jpaQuery.getResultSize() + " documents");
jpaQuery = fullTextEntityManager.createFullTextQuery(query8, InspectionMaster.class);
logService.log("TEST : Test search on all return " + jpaQuery.getResultSize() + " documents");
jpaQuery = fullTextEntityManager.createFullTextQuery(query9, InspectionMaster.class);
logService.log("TEST : Test search on all with *lpb* return " + jpaQuery.getResultSize() + " documents");
}
结果工作如下:
*** LOG [Sat Apr 23 17:25:08 CEST 2016] TEST : Test search on site.siteId = *lpb* return 16 documents
*** LOG [Sat Apr 23 17:25:08 CEST 2016] TEST : Test search on site.sitedescription = *france* return 16 documents
*** LOG [Sat Apr 23 17:25:08 CEST 2016] TEST : Test search on vendorNr = *s07610* return 3 documents
*** LOG [Sat Apr 23 17:25:08 CEST 2016] TEST : Test search on vendorDesc = *limited* return 1 documents
*** LOG [Sat Apr 23 17:25:08 CEST 2016] TEST : Test search on itemNr = *0023* return 4 documents
*** LOG [Sat Apr 23 17:25:08 CEST 2016] TEST : Test search on itemDesc = *28w* return 5 documents
*** LOG [Sat Apr 23 17:25:08 CEST 2016] TEST : Test search on whmPickLocation = *00* return 10 documents
*** LOG [Sat Apr 23 17:25:08 CEST 2016] TEST : Test search on all return 16 documents
*** LOG [Sat Apr 23 17:25:08 CEST 2016] TEST : Test search on all with *lpb* return 16 documents
我最终在我的项目中构建了一个搜索功能:
public Page<InspectionMaster> search(String text, Pageable pageable) {
// get the full text entity manager
FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search.getFullTextEntityManager(em);
// create the query using Hibernate Search query DSL
QueryBuilder queryBuilder = fullTextEntityManager
.getSearchFactory()
.buildQueryBuilder()
.forEntity(InspectionMaster.class)
.get();
// Add wildcard to always have a full search capability
text = "*" + text.toLowerCase() + "*";
// Build Query !
Query query = queryBuilder
.bool()
.should( queryBuilder.keyword().wildcard().onField("site.siteId").matching(text).createQuery() )
.should( queryBuilder.keyword().wildcard().onField("site.sitedescription").matching(text).createQuery() )
.should( queryBuilder.keyword().wildcard().onField("vendorNr").matching(text).createQuery() )
.should( queryBuilder.keyword().wildcard().onField("vendorDesc").matching(text).createQuery() )
.should( queryBuilder.keyword().wildcard().onField("itemNr").matching(text).createQuery() )
.should( queryBuilder.keyword().wildcard().onField("itemDesc").matching(text).createQuery() )
.should( queryBuilder.keyword().wildcard().onField("whmPickLocation").matching(text).createQuery() )
.createQuery();
// wrap Lucene query in an Hibernate Query object
FullTextQuery jpaQuery = fullTextEntityManager.createFullTextQuery(query, InspectionMaster.class);
jpaQuery.setFirstResult(pageable.getOffset());
jpaQuery.setMaxResults(pageable.getPageSize());
int resultSize = jpaQuery.getResultSize();
logService.log("Search for text = "+ text +" return " + jpaQuery.getResultSize() + " documents");
// execute search and return results (sorted by relevance as default)
@SuppressWarnings("unchecked")
List<InspectionMaster> results = jpaQuery.getResultList();
return new PageImpl<>(results, pageable, resultSize);
}
但这并不像预期的那样奏效。系统为某些关键字返回一些文档,但对于其他关键字,我什么也得不到。
我在此功能中复制/通过我的测试单元代码,我得到以下结果:
*** LOG [Sat Apr 23 17:23:18 CEST 2016] TEST : Test search on site.siteId = *lpb* return 0 documents
*** LOG [Sat Apr 23 17:23:18 CEST 2016] TEST : Test search on site.sitedescription = *france* return 0 documents
*** LOG [Sat Apr 23 17:23:18 CEST 2016] TEST : Test search on vendorNr = *s07610* return 3 documents
*** LOG [Sat Apr 23 17:23:18 CEST 2016] TEST : Test search on vendorDesc = *limited* return 0 documents
*** LOG [Sat Apr 23 17:23:18 CEST 2016] TEST : Test search on itemNr = *0023* return 4 documents
*** LOG [Sat Apr 23 17:23:18 CEST 2016] TEST : Test search on itemDesc = *28w* return 0 documents
*** LOG [Sat Apr 23 17:23:18 CEST 2016] TEST : Test search on whmPickLocation = *00* return 0 documents
*** LOG [Sat Apr 23 17:23:18 CEST 2016] TEST : Test search on all return 7 documents
*** LOG [Sat Apr 23 17:23:18 CEST 2016] TEST : Test search on all with *lpb* return 0 documents
正如您所看到的,搜索ItemNr和VendorNr的工作,但是对于其他人......没有。
我肯定错过了什么,但是????
非常欢迎任何帮助。提前谢谢。