Lucene查询语法

时间:2009-07-29 19:11:33

标签: lucene compass-lucene

我正在尝试使用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
}

4 个答案:

答案 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