@@ -16,8 +16,8 @@ import scala.jdk.CollectionConverters._
1616
1717object 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
0 commit comments