Lucene Request Syntax

I am trying to use Lucene to query a domain that has the following structure

Student 1-------* Attendance *---------1 Course 

The data in the area are given below.

 Course.name Attendance.mandatory Student.name ------------------------------------------------- cooking N Bob art Y Bob 

If I execute the "courseName:cooking AND mandatory:Y" , it returns Bob because Bob is on a cooking course and Bob is also attending a required course. However, what I really want to request is β€œstudents participating in a compulsory culinary course,” which in this case will not return to anyone.

Can this be formulated as a Lucene query? I actually use Compass, not Lucene directly, so I can use CompassQueryBuilder or the Lucene query language.

For completeness, the domain classes themselves are shown below. These classes are Grails class classes, but I use standard Compass annotations and Lucene query syntax.

 @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 } 
+1
source share
4 answers

What you are trying to do is sometimes called "scoped search" or "xml search" - the ability to search based on a set of related sub-elements. Lucene does not support this initially, but there are some tricks you can do to make it work.

You can put all the course data associated with the student in one field. Then raise the position of the term with a fixed amount (for example, 100) between the conditions for each course. You can then search by proximity with phrase queries or range queries to force matching attributes of the same course. So Solr supports multi-valued fields.

+4
source

Another workaround is to add a fake getter and index it

Sort of:

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

Try

 +courseName:cooking +mandatory:Y 

We use fairly similar queries, and this works for us:

 +ProdLineNum:1920b +HouseBrand:1 

This selects everything in the 1920b product line, which is also a generic brand.

-1
source

You can simply create the queries as a text string and then parse this to get the query object. Suppose you saw Apache Lucene - Query parsing syntax ?

-1
source

Source: https://habr.com/ru/post/895278/


All Articles