Я новичок в Apache Lucene или любых других движках fts, так что извините за это Я успешно внедрил Apache Lucene вместе с поисковой формой гибернации, НО, когда дело доходит до вложенных отношений, это работает только одинслой вниз, пока я понял и пытался до сих пор. Таким образом, я могу добиться поиска более двух вложенных объектов, вложенных ниже, например:
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
}
}
Как вы можете видеть, у меня есть заголовокполе, которое является другим отношением, на котором должно быть выполнено 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())
}
Как вы можетеу меня есть e "subCategory.title.en", который выдает исключение