Skip to content

Commit 3ec93ad

Browse files
committed
option to ignore empty query for analyzers with stop words
1 parent 1b188c5 commit 3ec93ad

File tree

5 files changed

+98
-44
lines changed

5 files changed

+98
-44
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,16 @@ MyDomainClass.search().list {
613613
}
614614
```
615615

616+
### Options
617+
618+
```groovy
619+
grails.plugins.hibernatesearch = {
620+
rebuildIndexOnStart false // see related section above
621+
throwOnEmptyQuery false // throw or not exception when Hibernate Search raises an EmptyQueryException
622+
fullTextFilter /* ... */ // see related section above
623+
}
624+
```
625+
616626
## Change log
617627

618628
### v2.0.2

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ buildscript {
1010
}
1111
}
1212

13-
version "2.0.2"
13+
version "2.0.3"
1414
group "org.grails.plugins"
1515

1616
apply plugin:"eclipse"

src/main/groovy/grails/plugins/hibernate/search/HibernateSearchConfig.groovy

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ class HibernateSearchConfig {
1717
private final FullTextSession fullTextSession
1818
private static final List MASS_INDEXER_METHODS = MassIndexer.methods.findAll { it.returnType == MassIndexer }*.name
1919

20+
boolean throwExceptionOnEmptyQuery
21+
2022
HibernateSearchConfig( Session session ) {
2123
this.fullTextSession = Search.getFullTextSession( session )
2224
}
@@ -55,6 +57,16 @@ class HibernateSearchConfig {
5557

5658
massIndexer = fullTextSession.createIndexer().startAndWait()
5759
}
60+
61+
/**
62+
* Throws exception if Hibernate Search raises an EmptyQueryException, (could occur if analyzer has stop words) default false
63+
*/
64+
def throwOnEmptyQuery( boolean throwException ) {
65+
66+
log.debug "throwExceptionOnEmptyQuery = " + throwException
67+
68+
throwExceptionOnEmptyQuery = throwException
69+
}
5870

5971
Object invokeMethod( String name, Object args ) {
6072
if ( name in MASS_INDEXER_METHODS ) {

src/main/groovy/grails/plugins/hibernate/search/HibernateSearchGrailsPlugin.groovy

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ class HibernateSearchGrailsPlugin extends Plugin {
1717

1818
private final static Logger log = LoggerFactory.getLogger(this)
1919

20+
public static HibernateSearchConfig pluginConfig;
21+
2022
def grailsVersion = "3.1.12 > *"
2123

2224
def profiles = ['web']
@@ -70,12 +72,12 @@ class HibernateSearchGrailsPlugin extends Plugin {
7072
log.info "* " + clazz.getSimpleName() + " is indexed"
7173
grailsClass.metaClass.static.search = {
7274

73-
new HibernateSearchQueryBuilder( clazz, applicationContext.sessionFactory.getCurrentSession() )
75+
new HibernateSearchQueryBuilder( clazz, applicationContext.sessionFactory.getCurrentSession(), pluginConfig )
7476
}
7577

7678
grailsClass.metaClass.search = {
7779
def instance = delegate
78-
new HibernateSearchQueryBuilder( clazz, instance, applicationContext.sessionFactory.getCurrentSession() )
80+
new HibernateSearchQueryBuilder( clazz, instance, applicationContext.sessionFactory.getCurrentSession(), pluginConfig )
7981
}
8082
}
8183
}
@@ -88,7 +90,8 @@ class HibernateSearchGrailsPlugin extends Plugin {
8890
log.debug 'hibernatesearch config found'
8991
Session session = applicationContext.sessionFactory.openSession();
9092

91-
hibernateSearchConfig.delegate = new HibernateSearchConfig( session )
93+
pluginConfig = new HibernateSearchConfig( session )
94+
hibernateSearchConfig.delegate = pluginConfig
9295
hibernateSearchConfig.resolveStrategy = Closure.DELEGATE_FIRST
9396
hibernateSearchConfig.call()
9497
}

src/main/groovy/grails/plugins/hibernate/search/HibernateSearchQueryBuilder.groovy

Lines changed: 69 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import org.hibernate.search.FullTextQuery
2626
import org.hibernate.search.FullTextSession
2727
import org.hibernate.search.MassIndexer
2828
import org.hibernate.search.Search
29+
import org.hibernate.search.exception.EmptyQueryException;
2930
import org.hibernate.search.query.dsl.FieldCustomization
3031
import org.hibernate.search.query.dsl.QueryBuilder
3132
import org.slf4j.Logger;
@@ -65,6 +66,38 @@ class HibernateSearchQueryBuilder {
6566
children << component
6667
}
6768

69+
/**
70+
* @return true if composite contains at least one valid (not empty) query
71+
*/
72+
protected boolean forEachQuery( Closure action ) {
73+
74+
boolean notEmpty = false;
75+
if (children) {
76+
77+
for (child in children) {
78+
try {
79+
80+
Query subQuery = child.createQuery();
81+
82+
action.delegate = subQuery
83+
action.resolveStrategy = Closure.DELEGATE_FIRST
84+
action.call(subQuery)
85+
notEmpty = true;
86+
87+
} catch (EmptyQueryException e) {
88+
if (HibernateSearchGrailsPlugin.pluginConfig.throwExceptionOnEmptyQuery) {
89+
throw e
90+
} else {
91+
log.warn 'empty Hibernate search query ignored! ' + child, e
92+
}
93+
}
94+
}
95+
96+
}
97+
98+
return notEmpty
99+
}
100+
68101
def toString( indent ) {
69102
[( "-" * indent ) + this.class.simpleName, children.collect { it.toString( indent + 1 ) }].flatten().findAll {it}.join( "\n" )
70103
}
@@ -100,54 +133,47 @@ class HibernateSearchQueryBuilder {
100133

101134
private static class MustNotComponent extends Composite {
102135
Query createQuery( ) {
103-
if ( children ) {
104136

105-
def query = queryBuilder.bool()
137+
def query = queryBuilder.bool()
138+
boolean notEmpty = forEachQuery { subQuery ->
139+
query = query.must( subQuery ).not()
140+
}
106141

107-
children*.createQuery().each {
108-
query = query.must( it ).not()
109-
}
110-
111-
query.createQuery()
112-
113-
} else {
114-
queryBuilder.all().createQuery()
115-
}
142+
if (notEmpty) {
143+
return query.createQuery()
144+
} else {
145+
return queryBuilder.all().createQuery()
146+
}
147+
116148
}
117149
}
118150
private static class MustComponent extends Composite {
119151
Query createQuery( ) {
120-
if ( children ) {
121-
122-
def query = queryBuilder.bool()
123-
124-
children*.createQuery().each {
125-
query = query.must( it )
126-
}
127-
128-
query.createQuery()
129-
130-
} else {
131-
queryBuilder.all().createQuery()
132-
}
152+
def query = queryBuilder.bool()
153+
boolean notEmpty = forEachQuery { subQuery ->
154+
query = query.must( subQuery )
155+
}
156+
157+
if (notEmpty) {
158+
return query.createQuery()
159+
} else {
160+
return queryBuilder.all().createQuery()
161+
}
133162
}
134163
}
135164

136165
private static class ShouldComponent extends Composite {
137166
Query createQuery( ) {
138-
if ( children ) {
139-
140-
def query = queryBuilder.bool()
141-
142-
children*.createQuery().each {
143-
query = query.should( it )
144-
}
145-
146-
query.createQuery()
147-
148-
} else {
149-
queryBuilder.all().createQuery()
150-
}
167+
def query = queryBuilder.bool()
168+
boolean notEmpty = forEachQuery { subQuery ->
169+
query = query.should( subQuery )
170+
}
171+
172+
if (notEmpty) {
173+
return query.createQuery()
174+
} else {
175+
return queryBuilder.all().createQuery()
176+
}
151177
}
152178
}
153179

@@ -219,6 +245,8 @@ class HibernateSearchQueryBuilder {
219245

220246
private static final List MASS_INDEXER_METHODS = MassIndexer.methods.findAll { it.returnType == MassIndexer }*.name
221247

248+
private final HibernateSearchConfig pluginConfig;
249+
222250
private final FullTextSession fullTextSession
223251
private final clazz
224252
private final instance
@@ -241,15 +269,16 @@ class HibernateSearchQueryBuilder {
241269

242270
Filter filter
243271

244-
HibernateSearchQueryBuilder( clazz, instance, Session session ) {
272+
HibernateSearchQueryBuilder( clazz, instance, Session session, HibernateSearchConfig pluginConfig ) {
245273
this.clazz = clazz
246274
this.fullTextSession = Search.getFullTextSession( session )
247275
this.instance = instance
248276
this.staticContext = instance == null
277+
this.pluginConfig = pluginConfig;
249278
}
250279

251-
HibernateSearchQueryBuilder( clazz, Session session ) {
252-
this( clazz, null, session )
280+
HibernateSearchQueryBuilder( clazz, Session session, HibernateSearchConfig pluginConfig ) {
281+
this( clazz, null, session, pluginConfig )
253282
}
254283

255284
private FullTextQuery createFullTextQuery( ) {

0 commit comments

Comments
 (0)