1

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 クエリとして定式化することは可能ですか? 実際には、Lucene を直接使用するのではなく、Compass を使用しているため、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

4 に答える 4

4

あなたがしようとしていることは、「スコープ検索」または「xml 検索」と呼ばれることがあります。これは、関連するサブ要素のセットに基づいて検索する機能です。Lucene はこれをネイティブにサポートしていませんが、機能させるためにできるいくつかのトリックがあります。

学生に関連付けられたすべてのコース データを 1 つのフィールドに入れることができます。次に、各コースのターム間でタームの位置を固定量 (100 など) だけ上げます。次に、フレーズ クエリまたはスパン クエリを使用して近接検索を実行し、1 つのコースの属性を強制的に一致させることができます。これが、Solr が多値フィールドをサポートする方法です。

于 2009-07-29T21:32:22.860 に答える
2

別の回避策は、偽のゲッターを追加してインデックスを作成することです

何かのようなもの:

@SearchableComponent
Course getCourseMandatory() {
    return course + mandatory;
}
于 2009-11-23T15:19:41.187 に答える
-1

試す

+courseName:cooking +mandatory:Y

私たちは非常によく似たクエリを使用し、これは私たちのために機能します:

+ProdLineNum:1920b +HouseBrand:1

これにより、自社ブランド(ジェネリック)でもある製品ライン1920bのすべてが選択されます。

于 2009-07-29T19:31:20.480 に答える
-1

クエリをテキスト文字列として作成し、それを解析してクエリオブジェクトを取得するだけです。Apache Lucene-クエリパーサー構文を見たことがあると思いますか?

于 2009-07-29T19:34:01.160 に答える