Skip to content

Commit 9e73ce1

Browse files
committed
feat: support lucene query converter support search with long value on string field
1 parent 3df7127 commit 9e73ce1

File tree

7 files changed

+150
-92
lines changed

7 files changed

+150
-92
lines changed

src/main/scala/dev/mongocamp/driver/mongodb/lucene/LuceneQueryConverter.scala

Lines changed: 110 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import scala.jdk.CollectionConverters._
1616

1717
object LuceneQueryConverter extends LazyLogging {
1818

19-
def toDocument(query: Query): Bson = {
20-
getMongoDbSearchMap(query, false)
19+
def toDocument(query: Query, searchWithValueAndString: Boolean = false): Bson = {
20+
getMongoDbSearchMap(query, negated = false, searchWithValueAndString)
2121
}
2222

2323
def parse(queryString: String, defaultField: String): Query = {
@@ -30,59 +30,59 @@ object LuceneQueryConverter extends LazyLogging {
3030
query
3131
}
3232

33-
private def getMongoDbSearchMap(query: Query, negated: Boolean): Map[String, Any] = {
33+
private def getMongoDbSearchMap(query: Query, negated: Boolean, searchWithValueAndString: Boolean): Map[String, Any] = {
3434
val searchMapResponse = mutable.Map[String, Any]()
3535
query match {
36-
case booleanQuery: BooleanQuery =>
37-
appendBooleanQueryToSearchMap(searchMapResponse, booleanQuery)
38-
case termRangeQuery: TermRangeQuery =>
39-
appendTermRangeQueryToSearchMap(negated, searchMapResponse, termRangeQuery)
40-
case termQuery: TermQuery =>
41-
appendTermQueryToSearchMap(negated, searchMapResponse, termQuery)
42-
case query: PrefixQuery =>
43-
appendPrefixQueryToSearchMap(negated, searchMapResponse, query)
44-
case query: WildcardQuery =>
45-
appendWildCardQueryToSearchMap(negated, searchMapResponse, query)
46-
case query: PhraseQuery =>
47-
appendPhraseQueryToSearchMap(negated, searchMapResponse, query)
36+
case booleanQuery: BooleanQuery => appendBooleanQueryToSearchMap(searchMapResponse, booleanQuery, searchWithValueAndString)
37+
case termRangeQuery: TermRangeQuery => appendTermRangeQueryToSearchMap(negated, searchMapResponse, termRangeQuery, searchWithValueAndString)
38+
case termQuery: TermQuery => appendTermQueryToSearchMap(negated, searchMapResponse, termQuery, searchWithValueAndString)
39+
case query: PrefixQuery => appendPrefixQueryToSearchMap(negated, searchMapResponse, query)
40+
case query: WildcardQuery => appendWildCardQueryToSearchMap(negated, searchMapResponse, query)
41+
case query: PhraseQuery => appendPhraseQueryToSearchMap(negated, searchMapResponse, query)
4842
case a: Any =>
49-
logger.error(s"Unexpected QueryType <${a.getClass.getSimpleName}>")
43+
val simpleNameOption = Option(a.getClass.getSimpleName).filterNot(s => s.trim.equalsIgnoreCase(""))
44+
if (simpleNameOption.isDefined) {
45+
logger.error(s"Unexpected QueryType <${a.getClass.getSimpleName}>")
46+
}
5047
}
5148
searchMapResponse.toMap
52-
5349
}
54-
private def appendBooleanQueryToSearchMap(searchMapResponse: mutable.Map[String, Any], booleanQuery: BooleanQuery): Unit = {
50+
51+
private def appendBooleanQueryToSearchMap(
52+
searchMapResponse: mutable.Map[String, Any],
53+
booleanQuery: BooleanQuery,
54+
searchWithValueAndString: Boolean
55+
): Unit = {
5556
val subQueries = booleanQuery.clauses().asScala
5657
val listOfAnd = ArrayBuffer[Map[String, Any]]()
5758
val listOfOr = ArrayBuffer[Map[String, Any]]()
5859
var nextTypeAnd = true
59-
subQueries
60-
.foreach(c => {
61-
val queryMap = getMongoDbSearchMap(c.getQuery, c.isProhibited)
62-
var thisTypeAnd = true
60+
subQueries.foreach(c => {
61+
val queryMap = getMongoDbSearchMap(c.getQuery, c.isProhibited, searchWithValueAndString)
62+
var thisTypeAnd = true
6363

64-
if (c.getOccur == Occur.MUST) {
65-
thisTypeAnd = true
66-
}
67-
else if (c.getOccur == Occur.SHOULD) {
68-
thisTypeAnd = false
69-
}
70-
else if (c.getOccur == Occur.MUST_NOT) {
71-
// searchMapResponse ++= queryMap
72-
}
73-
else {
74-
logger.error(s"Unexpected Occur <${c.getOccur.name()}>")
75-
throw new NotSupportedException(s"${c.getOccur.name()} currently not supported")
76-
}
64+
if (c.getOccur == Occur.MUST) {
65+
thisTypeAnd = true
66+
}
67+
else if (c.getOccur == Occur.SHOULD) {
68+
thisTypeAnd = false
69+
}
70+
else if (c.getOccur == Occur.MUST_NOT) {
71+
// searchMapResponse ++= queryMap
72+
}
73+
else {
74+
logger.error(s"Unexpected Occur <${c.getOccur.name()}>")
75+
throw new NotSupportedException(s"${c.getOccur.name()} currently not supported")
76+
}
7777

78-
if (nextTypeAnd && thisTypeAnd) {
79-
listOfAnd += queryMap
80-
}
81-
else {
82-
listOfOr += queryMap
83-
}
84-
nextTypeAnd = thisTypeAnd
85-
})
78+
if (nextTypeAnd && thisTypeAnd) {
79+
listOfAnd += queryMap
80+
}
81+
else {
82+
listOfOr += queryMap
83+
}
84+
nextTypeAnd = thisTypeAnd
85+
})
8686

8787
if (listOfAnd.nonEmpty) {
8888
searchMapResponse.put("$and", listOfAnd.toList)
@@ -91,25 +91,77 @@ object LuceneQueryConverter extends LazyLogging {
9191
searchMapResponse.put("$or", listOfOr.toList)
9292
}
9393
}
94-
private def appendTermRangeQueryToSearchMap(negated: Boolean, searchMapResponse: mutable.Map[String, Any], termRangeQuery: TermRangeQuery): Unit = {
95-
val lowerBound = checkAndConvertValue(new String(termRangeQuery.getLowerTerm.bytes))
96-
val upperBound = checkAndConvertValue(new String(termRangeQuery.getUpperTerm.bytes))
97-
val inRangeSearch = Map("$lte" -> upperBound, "$gte" -> lowerBound)
94+
95+
private def appendTermRangeQueryToSearchMap(
96+
negated: Boolean,
97+
searchMapResponse: mutable.Map[String, Any],
98+
termRangeQuery: TermRangeQuery,
99+
searchWithValueAndString: Boolean
100+
): Unit = {
101+
val lowerBoundString = new String(termRangeQuery.getLowerTerm.bytes)
102+
val lowerBound = checkAndConvertValue(lowerBoundString)
103+
val upperBoundString = new String(termRangeQuery.getUpperTerm.bytes)
104+
val upperBound = checkAndConvertValue(upperBoundString)
105+
106+
val searchWithStringValue = searchWithValueAndString && (lowerBoundString != lowerBound || upperBoundString != upperBound)
107+
108+
val inRangeSearch = Map("$lte" -> upperBound, "$gte" -> lowerBound)
109+
val inRangeStringSearch = Map("$lte" -> upperBoundString, "$gte" -> lowerBoundString)
98110
if (negated) {
99-
searchMapResponse.put(termRangeQuery.getField, Map("$not" -> inRangeSearch))
111+
if (searchWithStringValue) {
112+
searchMapResponse.put(
113+
"$and",
114+
List(Map(termRangeQuery.getField -> Map("$not" -> inRangeSearch)), Map(termRangeQuery.getField -> Map("$not" -> inRangeStringSearch)))
115+
)
116+
}
117+
else {
118+
searchMapResponse.put(termRangeQuery.getField, Map("$not" -> inRangeSearch))
119+
}
100120
}
101121
else {
102-
searchMapResponse.put(termRangeQuery.getField, inRangeSearch)
122+
if (searchWithStringValue) {
123+
searchMapResponse.put(
124+
"$or",
125+
List(Map(termRangeQuery.getField -> inRangeSearch), Map(termRangeQuery.getField -> inRangeStringSearch))
126+
)
127+
}
128+
else {
129+
searchMapResponse.put(termRangeQuery.getField, inRangeSearch)
130+
}
103131
}
104132
}
105-
private def appendTermQueryToSearchMap(negated: Boolean, searchMapResponse: mutable.Map[String, Any], termQuery: TermQuery): Unit = {
133+
134+
private def appendTermQueryToSearchMap(
135+
negated: Boolean,
136+
searchMapResponse: mutable.Map[String, Any],
137+
termQuery: TermQuery,
138+
searchWithValueAndString: Boolean
139+
): Unit = {
140+
val convertedValue = checkAndConvertValue(termQuery.getTerm.text())
106141
if (negated) {
107-
searchMapResponse.put(termQuery.getTerm.field(), Map("$ne" -> checkAndConvertValue(termQuery.getTerm.text())))
142+
if (!searchWithValueAndString || convertedValue == termQuery.getTerm.text()) {
143+
searchMapResponse.put(termQuery.getTerm.field(), Map("$ne" -> convertedValue))
144+
}
145+
else {
146+
searchMapResponse.put(
147+
"$and",
148+
List(Map(termQuery.getTerm.field() -> Map("$ne" -> convertedValue)), Map(termQuery.getTerm.field() -> Map("$ne" -> termQuery.getTerm.text())))
149+
)
150+
}
108151
}
109152
else {
110-
searchMapResponse.put(termQuery.getTerm.field(), Map("$eq" -> checkAndConvertValue(termQuery.getTerm.text())))
153+
if (!searchWithValueAndString || convertedValue == termQuery.getTerm.text()) {
154+
searchMapResponse.put(termQuery.getTerm.field(), Map("$eq" -> convertedValue))
155+
}
156+
else {
157+
searchMapResponse.put(
158+
"$or",
159+
List(Map(termQuery.getTerm.field() -> Map("$eq" -> convertedValue)), Map(termQuery.getTerm.field() -> Map("$eq" -> termQuery.getTerm.text())))
160+
)
161+
}
111162
}
112163
}
164+
113165
private def appendPrefixQueryToSearchMap(negated: Boolean, searchMapResponse: mutable.Map[String, Any], query: PrefixQuery): Unit = {
114166
val searchValue = s"${checkAndConvertValue(query.getPrefix.text())}(.*?)"
115167
val listOfSearches: List[Bson] = List(Map(query.getField -> generateRegexQuery(s"$searchValue", "i")))
@@ -120,6 +172,7 @@ object LuceneQueryConverter extends LazyLogging {
120172
searchMapResponse ++= Map("$and" -> listOfSearches)
121173
}
122174
}
175+
123176
private def appendWildCardQueryToSearchMap(negated: Boolean, searchMapResponse: mutable.Map[String, Any], query: WildcardQuery): Unit = {
124177
val searchValue = checkAndConvertValue(query.getTerm.text().replace("*", "(.*?)"))
125178
if (negated) {
@@ -129,20 +182,21 @@ object LuceneQueryConverter extends LazyLogging {
129182
searchMapResponse.put(query.getField, generateRegexQuery(s"$searchValue", "i"))
130183
}
131184
}
185+
132186
private def appendPhraseQueryToSearchMap(negated: Boolean, searchMapResponse: mutable.Map[String, Any], query: PhraseQuery): Unit = {
133-
val listOfSearches = query.getTerms
134-
.map(term => Map(term.field() -> generateRegexQuery(s"(.*?)${checkAndConvertValue(term.text())}(.*?)", "i")))
135-
.toList
187+
val listOfSearches = query.getTerms.map(term => Map(term.field() -> generateRegexQuery(s"(.*?)${checkAndConvertValue(term.text())}(.*?)", "i"))).toList
136188
if (negated) {
137189
searchMapResponse.put("$nor", listOfSearches)
138190
}
139191
else {
140192
searchMapResponse ++= Map("$and" -> listOfSearches)
141193
}
142194
}
195+
143196
private def generateRegexQuery(pattern: String, options: String): Map[String, String] = {
144197
Map("$regex" -> pattern, "$options" -> options)
145198
}
199+
146200
private def checkAndConvertValue(s: String): Any = {
147201

148202
def checkOrReturn[A <: Any](f: () => A): Option[A] = {
@@ -156,7 +210,7 @@ object LuceneQueryConverter extends LazyLogging {
156210
}
157211
}
158212
catch {
159-
case e: Exception => None
213+
case _: Exception => None
160214
}
161215
}
162216

src/main/scala/dev/mongocamp/driver/mongodb/lucene/MongoCampLuceneAnalyzer.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,11 @@ class MongoCampLuceneAnalyzer(stopWords: CharArraySet = CharArraySet.EMPTY_SET,
1010
override protected def createComponents(fieldName: String): Analyzer.TokenStreamComponents = {
1111
val src = new StandardTokenizer
1212
src.setMaxTokenLength(maxTokenLength)
13-
val tok: TokenStream = new StopFilter(src, stopwords)
13+
val tok: TokenStream = new StopFilter(src, stopWords)
1414
new Analyzer.TokenStreamComponents(
1515
(r: Reader) => {
1616
src.setMaxTokenLength(maxTokenLength)
1717
src.setReader(r)
18-
1918
},
2019
tok
2120
)

src/test/resources/json/people.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{ "_id" : { "$oid" : "5e9ef66185c0145fa5d3c447" }, "id" : { "$numberLong" : "0" }, "guid" : "a17be99a-8913-4bb6-8f14-16d4fa1b3559", "isActive" : true, "balance" : 3349.0, "picture" : "http://placehold.it/32x32", "age" : 25, "name" : "Cheryl Hoffman", "gender" : "female", "email" : "cherylhoffman@melbacor.com", "phone" : "+1 (942) 477-2284", "address" : "308 Just Court, Rose, Maine, 4477", "about" : "Adipisicing aliquip deserunt mollit veniam. Quis mollit cupidatat laboris dolor incididunt esse voluptate amet aute. Sit labore magna minim ex aliquip do labore ullamco labore labore.\r\n", "registered" : { "$date" : "2014-02-08T02:10:36.000+0000" }, "tags" : [ "esse", "sunt", "exercitation", "nostrud", "aliqua", "voluptate", "ullamco" ], "friends" : [ { "id" : { "$numberLong" : "0" }, "name" : "Castaneda Mccullough" }, { "id" : { "$numberLong" : "1" }, "name" : "Black Whitaker" }, { "id" : { "$numberLong" : "2" }, "name" : "Wendy Strong" }, { "id" : { "$numberLong" : "3" }, "name" : "Dixie Reilly" }, { "id" : { "$numberLong" : "4" }, "name" : "Deleon Turner" } ], "greeting" : "Hello, Cheryl Hoffman! You have 9 unread messages.", "favoriteFruit" : "apple" }
1+
{ "_id" : { "$oid" : "5e9ef66185c0145fa5d3c447" }, "id" : { "$numberLong" : "0" }, "guid" : "a17be99a-8913-4bb6-8f14-16d4fa1b3559", "isActive" : true, "balance" : 3349.0, "picture" : "http://placehold.it/32x32", "age" : 25, "name" : "Cheryl Hoffman", "gender" : "female", "email" : "cherylhoffman@melbacor.com", "phone" : "+1 (942) 477-2284", "address" : "308 Just Court, Rose, Maine, 4477", "about" : "Adipisicing aliquip deserunt mollit veniam. Quis mollit cupidatat laboris dolor incididunt esse voluptate amet aute. Sit labore magna minim ex aliquip do labore ullamco labore labore.\r\n", "registered" : { "$date" : "2014-02-08T02:10:36.000+0000" }, "tags" : [ "esse", "sunt", "exercitation", "nostrud", "aliqua", "voluptate", "ullamco" ], "friends" : [ { "id" : { "$numberLong" : "0" }, "name" : "Castaneda Mccullough" }, { "id" : { "$numberLong" : "1" }, "name" : "Black Whitaker" }, { "id" : { "$numberLong" : "2" }, "name" : "Wendy Strong" }, { "id" : { "$numberLong" : "3" }, "name" : "Dixie Reilly" }, { "id" : { "$numberLong" : "4" }, "name" : "Deleon Turner" } ], "greeting" : "Hello, Cheryl Hoffman! You have 9 unread messages.", "favoriteFruit" : "apple", "stringNumber": "123" }
22
{ "_id" : { "$oid" : "5e9ef66185c0145fa5d3c448" }, "id" : { "$numberLong" : "1" }, "guid" : "19ebe4fe-f860-4cbc-ac0a-664a418e2173", "isActive" : true, "balance" : 2316.0, "picture" : "http://placehold.it/32x32", "age" : 25, "name" : "Bowen Leon", "gender" : "male", "email" : "bowenleon@inrt.com", "phone" : "+1 (904) 457-2017", "address" : "138 Miami Court, Urbana, Kansas, 1034", "about" : "Commodo in mollit laboris incididunt excepteur nulla cillum sunt do occaecat Lorem. Excepteur esse id magna pariatur irure anim officia exercitation veniam anim dolor. Sunt irure est dolore nisi nulla nulla. Nostrud aliquip exercitation ut adipisicing esse ullamco incididunt mollit laborum duis exercitation. Ipsum commodo excepteur nulla sit irure laboris magna ipsum Lorem.\r\n", "registered" : { "$date" : "2014-01-26T16:08:40.000+0000" }, "tags" : [ "ipsum", "qui", "proident", "sunt", "cillum", "veniam", "laboris" ], "friends" : [ { "id" : { "$numberLong" : "0" }, "name" : "Reyes Velasquez" }, { "id" : { "$numberLong" : "1" }, "name" : "Rosalie Hooper" }, { "id" : { "$numberLong" : "2" }, "name" : "Alyssa David" } ], "greeting" : "Hello, Bowen Leon! You have 9 unread messages.", "favoriteFruit" : "apple" }
33
{ "_id" : { "$oid" : "5e9ef66185c0145fa5d3c449" }, "id" : { "$numberLong" : "2" }, "guid" : "6ee53e07-2e61-48cd-9bc9-b3505a0438f3", "isActive" : false, "balance" : 1527.0, "picture" : "http://placehold.it/32x32", "age" : 40, "name" : "Cecilia Lynn", "gender" : "female", "email" : "cecilialynn@medicroix.com", "phone" : "+1 (875) 525-3138", "address" : "124 Herzl Street, Greenwich, Arkansas, 5309", "about" : "Esse adipisicing ipsum esse consectetur eu ad sunt sit culpa enim velit elit velit deserunt. Aliqua nulla et laboris nulla aute excepteur Lorem. Ut aliquip non excepteur exercitation consectetur anim est ex irure dolore ut. Consequat enim enim dolor excepteur mollit consectetur. Magna sunt reprehenderit est quis.\r\n", "registered" : { "$date" : "2014-02-21T23:13:05.000+0000" }, "tags" : [ "eiusmod", "minim", "magna", "est", "laborum", "nisi", "qui" ], "friends" : [ { "id" : { "$numberLong" : "0" }, "name" : "Erika Harmon" }, { "id" : { "$numberLong" : "1" }, "name" : "Horn Larsen" }, { "id" : { "$numberLong" : "2" }, "name" : "Gertrude Fuller" }, { "id" : { "$numberLong" : "3" }, "name" : "Spencer Hutchinson" }, { "id" : { "$numberLong" : "4" }, "name" : "Beryl Buckley" } ], "greeting" : "Hello, Cecilia Lynn! You have 7 unread messages.", "favoriteFruit" : "strawberry" }
44
{ "_id" : { "$oid" : "5e9ef66185c0145fa5d3c44a" }, "id" : { "$numberLong" : "3" }, "guid" : "a01c8bb6-95ac-4235-b6b3-475734f0dd92", "isActive" : false, "balance" : 2682.0, "picture" : "http://placehold.it/32x32", "age" : 24, "name" : "Sylvia Ortega", "gender" : "female", "email" : "sylviaortega@viagrand.com", "phone" : "+1 (983) 470-3157", "address" : "617 Vernon Avenue, Advance, Connecticut, 7787", "about" : "Tempor aliquip dolor excepteur proident ex magna commodo laboris. Ullamco ex esse excepteur nostrud. Duis ex anim pariatur dolore ut irure. Consequat non Lorem laborum esse anim magna consequat voluptate dolor elit. Mollit sint consequat ipsum minim id anim aute reprehenderit eu velit voluptate commodo.\r\n", "registered" : { "$date" : "2014-01-13T07:33:15.000+0000" }, "tags" : [ "ut", "culpa", "reprehenderit", "ad", "amet", "officia", "nostrud" ], "friends" : [ { "id" : { "$numberLong" : "0" }, "name" : "Ferrell Rhodes" }, { "id" : { "$numberLong" : "1" }, "name" : "Ana Guy" }, { "id" : { "$numberLong" : "2" }, "name" : "Rosanne Griffin" }, { "id" : { "$numberLong" : "3" }, "name" : "Morrow Adams" }, { "id" : { "$numberLong" : "4" }, "name" : "Keri White" }, { "id" : { "$numberLong" : "5" }, "name" : "Tracey Sykes" } ], "greeting" : "Hello, Sylvia Ortega! You have 9 unread messages.", "favoriteFruit" : "apple" }

src/test/scala/dev/mongocamp/driver/mongodb/dao/PersonDAOSpec.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ class PersonDAOSpec extends PersonSpecification with MongoImplicits {
1919
}
2020

2121
"support columnNames" in {
22-
val columnNames = PersonDAO.columnNames(100)
23-
columnNames.size mustEqual 18
22+
val columnNames = PersonDAO.columnNames(200)
23+
columnNames.size mustEqual 19
2424
}
2525

2626
"support results" in {

src/test/scala/dev/mongocamp/driver/mongodb/gridfs/GridFSDatabaseSpec.scala

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,12 @@ package dev.mongocamp.driver.mongodb.gridfs
22

33
import better.files.File
44
import dev.mongocamp.driver.mongodb._
5-
import dev.mongocamp.driver.mongodb.test.TestDatabase._
65
import dev.mongocamp.driver.mongodb.model.ImageMetadata
6+
import dev.mongocamp.driver.mongodb.test.TestDatabase._
77
import org.bson.types.ObjectId
88
import org.specs2.mutable.Specification
99
import org.specs2.specification.BeforeAll
1010

11-
import scala.io.Source
12-
1311
class GridFSDatabaseSpec extends Specification with GridfsDatabaseFunctions with BeforeAll {
1412

1513
"GridFSDatabase" should {
@@ -58,7 +56,7 @@ class GridFSDatabaseSpec extends Specification with GridfsDatabaseFunctions with
5856
files.head.getMetadata.get("name").toString must be equalTo "logo2"
5957

6058
// update complete metadata for one file
61-
updateMetadata(files.head, ImageMetadata("logo22", group = "logos"))
59+
updateMetadata(files.head, ImageMetadata("logo22"))
6260
// update metadata entry for all files
6361
updateMetadataElements(Map(), Map("group" -> "logos3", "newKey" -> "newEntryValue"))
6462

@@ -80,7 +78,7 @@ class GridFSDatabaseSpec extends Specification with GridfsDatabaseFunctions with
8078
}
8179

8280
override def beforeAll(): Unit = {
83-
dropImages
81+
dropImages()
8482
insertImage(ImageDAOSourcePath + "scala-logo.jpg", ImageMetadata("logo2", indexSet = Set(5, 6, 7)))
8583
imagesCount must be equalTo 1
8684

src/test/scala/dev/mongocamp/driver/mongodb/lucene/LuceneSearchSpec.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ class LuceneSearchSpec extends PersonSpecification {
99

1010
"LuceneSearch" should {
1111

12+
"search with with number in string" in {
13+
val luceneQuery = LuceneQueryConverter.parse("stringNumber: 123", "id")
14+
val search2 = PersonDAO.find(LuceneQueryConverter.toDocument(luceneQuery), sortByBalance).resultList()
15+
search2 must haveSize(0)
16+
val search = PersonDAO.find(LuceneQueryConverter.toDocument(luceneQuery, searchWithValueAndString = true), sortByBalance).resultList()
17+
search must haveSize(1)
18+
search.head.age mustEqual 25
19+
search.head.name mustEqual "Cheryl Hoffman"
20+
}
21+
1222
"search with extended query" in {
1323
val luceneQuery = LuceneQueryConverter.parse("(favoriteFruit:\"apple\" AND age:\"25\") OR name:*Cecile* AND -active:false AND 123", "id")
1424
// #region lucene-parser-with-explicit

0 commit comments

Comments
 (0)