我正在尝试使用Lucene来查询具有以下结构的域
Student 1-------* Attendance *---------1 Course
域中的数据总结如下
Course.name Attendance.mandatory Student.name
-------------------------------------------------
cooking N Bob
art Y Bob
如果我执行查询"courseName:cooking AND mandatory:Y"
,它会返回Bob,因为Bob正在参加烹饪课程,Bob也参加了强制性课程。但是,我 想要查询的内容是“参加强制性烹饪课程的学生”,在这种情况下会返回任何人。
是否可以将其表示为Lucene查询?我实际上是在使用Compass而不是Lucene,因此我可以使用CompassQueryBuilder或Lucene的查询语言。
为了完整起见,域类本身如下所示。这些类是Grails域类,但我使用标准的Compass注释和Lucene查询语法。
@Searchable
class Student {
@SearchableProperty(accessor = 'property')
String name
static hasMany = [attendances: Attendance]
@SearchableId(accessor = 'property')
Long id
@SearchableComponent
Set<Attendance> getAttendances() {
return attendances
}
}
@Searchable(root = false)
class Attendance {
static belongsTo = [student: Student, course: Course]
@SearchableProperty(accessor = 'property')
String mandatory = "Y"
@SearchableId(accessor = 'property')
Long id
@SearchableComponent
Course getCourse() {
return course
}
}
@Searchable(root = false)
class Course {
@SearchableProperty(accessor = 'property', name = "courseName")
String name
@SearchableId(accessor = 'property')
Long id
}
答案 0 :(得分:4)
您尝试做的有时称为“范围搜索”或“xml搜索” - 基于一组相关子元素进行搜索的功能。 Lucene本身并不支持这种做法,但是你可以采取一些技巧来实现它。
您可以将与学生相关的所有课程数据放在一个字段中。然后在每个课程的术语之间将术语位置按固定量(如100)进行冲击。然后,您可以使用短语查询或跨度查询进行邻近搜索,以强制匹配单个课程的属性。这就是Solr如何支持多值字段。
答案 1 :(得分:2)
另一种解决方法是添加假冒的getter并将其编入索引
类似的东西:
@SearchableComponent
Course getCourseMandatory() {
return course + mandatory;
}
答案 2 :(得分:-1)
尝试
+courseName:cooking +mandatory:Y
我们使用非常相似的查询,这对我们有用:
+ProdLineNum:1920b +HouseBrand:1
这将选择产品系列1920b中的所有产品系列(通用)。
答案 3 :(得分:-1)
您可以只创建查询作为文本字符串,然后解析它以获取您的查询对象。假设您已经看过Apache Lucene - Query Parser Syntax?