【问题标题】:Lucene Query SyntaxLucene 查询语法
【发布时间】:2009-07-29 19:11:32
【问题描述】:

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

【问题讨论】:

    标签: lucene compass-lucene


    【解决方案1】:

    您尝试执行的操作有时称为“范围搜索”或“xml 搜索”——基于一组相关子元素进行搜索的能力。 Lucene 本身不支持此功能,但您可以采取一些技巧使其正常工作。

    您可以将与学生关联的所有课程数据放在一个字段中。然后在每门课程的术语之间将术语位置提高一个固定的量(如 100)。然后,您可以使用短语查询或跨度查询进行邻近搜索,以强制匹配单个课程的属性。这就是 Solr 支持多值字段的方式。

    【讨论】:

      【解决方案2】:

      另一种解决方法是添加虚假的 getter 并将其编入索引

      类似:

      @SearchableComponent
      Course getCourseMandatory() {
          return course + mandatory;
      }
      

      【讨论】:

        【解决方案3】:

        试试

        +courseName:cooking +mandatory:Y
        

        我们使用非常相似的查询,这对我们有用:

        +ProdLineNum:1920b +HouseBrand:1
        

        这会选择产品线 1920b 中也是自有品牌(通用)的所有产品。

        【讨论】:

        • 感谢您的建议,但它不起作用 - 我得到与省略“+”符号时相同的结果
        【解决方案4】:

        您可以将查询创建为文本字符串,然后对其进行解析以获取您的查询对象。假设你见过Apache Lucene - Query Parser Syntax

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-21
          • 2017-06-12
          • 2020-03-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多