【发布时间】:2019-10-15 09:35:45
【问题描述】:
我是 apache lucene 或任何其他 fts 引擎的新手,对此深感抱歉 我已经成功地实现了 apache lucene 和 hibernate search orm 但是当涉及到嵌套关系时,只要我理解并尝试过,它只工作一层。所以我可以实现搜索多于两层的嵌套对象,如下所示
应在此模型上执行 FTS,特别是字段 User 和 UserSubCategory
@Entity
@org.hibernate.search.annotations.Indexed
class SubCategoryUserManyToMany(
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id", nullable = false)
@IndexedEmbedded
var user: User? = null,
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "category_id", nullable = false)
@IndexedEmbedded
var subCategory: UserSubCategory? = null,
@Field(index = Index.NO)
var jobType: JobType?= JobType.HOURLY,
@Field(index = Index.NO)
var price: Long = 0
): BaseModel()
我正在对用户模型的两个字段进行 fts,名字和姓氏。它工作得很好
@Entity
@Table(name = "users")
class User() : BaseModel() {
@Column(unique = true, name = "email")
@NotBlank
@Email
var email: String? = null
@Column(name = "firstname")
@Size(max = 100)
@Field
var firstname: String? = null
@Column(name = "lastname")
@Size(max = 100)
@Field
var lastname: String? = null
@Column(name = "midname")
@Size(max = 100)
var midname: String? = null
@Column(name = "password")
@Size(max = 100)
var password: String? = null
@NotBlank
@Column(name = "phone", unique = true)
@Size(max = 100)
var phone: String? = null
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "user_roles",
joinColumns = [JoinColumn(name = "user_id", referencedColumnName = "id")],
inverseJoinColumns = [JoinColumn(name = "role_id", referencedColumnName = "id")])
var roles: MutableList<Role> = mutableListOf()
//TODO CATEGORY RELATIONSHIPS
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
@ContainedIn
var subCategoryUserManyToMany: MutableList<SubCategoryUserManyToMany> = mutableListOf()
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "user_images_many_to_many",
joinColumns = [JoinColumn(name = "user_id", referencedColumnName = "id")],
inverseJoinColumns = [JoinColumn(name = "attachment_id", referencedColumnName = "id")])
var images: MutableList<Attachment> = mutableListOf()
constructor(id: Long) : this() {
this.id = id
}
}
然而,当涉及到 UserSubCategory 时,
@Entity
class UserSubCategory (
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "category_id", nullable = false)
var category: UserCategory? = null,
@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "title_id", nullable = false)
var title: TextValueShort? = null,
@OneToMany(mappedBy = "subCategory", fetch = FetchType.LAZY)
@ContainedIn
var subCategoryUserManyToMany: MutableList<SubCategoryUserManyToMany> = mutableListOf(),
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "master_subcategory_job_descriptions",
joinColumns = [JoinColumn(name = "sub_cat_id", referencedColumnName = "id")],
inverseJoinColumns = [JoinColumn(name = "text_id", referencedColumnName = "id")])
var whatShouldBeDoneList: MutableList<TextValueMedium> = mutableListOf()
) : BaseModel(){
constructor(id: Long): this(){
this.id = id
}
}
如您所见,我有 title 字段,这是应该进行 FTS 的另一种关系 型号
@Entity
@Table(name = "txt_value_short")
class TextValueShort {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
var id: Long? = null
@Size(max=150)
var ru : String? = null
@Size(max=150)
var en : String? = null
@Size(max=150)
var uz : String? = null
}
这是我的搜索功能
override fun masterSearch(searchTerm: String, fields: Array<String>, pageNo: Int, resultsPerPage: Int): Page<SubCategoryUserManyToMany> {
val fullTextEntityManager = Search.getFullTextEntityManager(entityManager)
val qb = fullTextEntityManager.searchFactory.buildQueryBuilder().forEntity(SubCategoryUserManyToMany::class.java).get()
val luceneQuery: org.apache.lucene.search.Query = qb
.bool()
.should(qb.keyword().onFields("user.firstname", "user.lastname", "subCategory.title.en").matching(searchTerm).createQuery())
.should(qb.keyword().wildcard().onFields("user.firstname", "user.lastname", "subCategory.title.en").matching("*$searchTerm*").createQuery())
.createQuery()
val jpaQuery = fullTextEntityManager.createFullTextQuery(luceneQuery, SubCategoryUserManyToMany::class.java)
jpaQuery.maxResults = resultsPerPage
jpaQuery.firstResult = (pageNo) * resultsPerPage
var result = listOf<SubCategoryUserManyToMany>()
try {
result = jpaQuery.resultList as List<SubCategoryUserManyToMany>
}catch (ex: Exception){}
val page = PageRequest(pageNo, resultsPerPage )
return PageImpl(result, page, result.size.toLong())
}
如你所见,我有一个抛出异常的“subCategory.title.en”
【问题讨论】:
标签: hibernate spring-boot lucene hibernate-search