Skip to content

Commit

Permalink
query doc strings
Browse files Browse the repository at this point in the history
  • Loading branch information
samspills committed Sep 22, 2023
1 parent 39a58cf commit e75f1d3
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 1 deletion.
2 changes: 1 addition & 1 deletion core/src/main/scala/pink/cozydev/lucille/Parser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ object Parser {
val fuzzySoft: P[String] = term.soft <* pchar('~')

/** Parse a fuzzy term query
* e.g. 'cat~', 'cat~t'
* e.g. 'cat~', 'cat~1'
*/
val fuzzyT: P[Fuzzy] = (fuzzySoft ~ int.?).map { case (q, n) =>
Fuzzy(q, n)
Expand Down
73 changes: 73 additions & 0 deletions core/src/main/scala/pink/cozydev/lucille/Query.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
package pink.cozydev.lucille

import cats.data.NonEmptyList
import scala.annotation.meta.field

/** A trait for all queries */
sealed trait Query extends Product with Serializable {

/** Builds a new query by applying a `Term => Query` function to a Term if it is in the last position.
Expand All @@ -28,11 +30,13 @@ sealed trait Query extends Product with Serializable {
def mapLastTerm(f: Query.Term => Query): Query
}

/** A trait for all leaf node queries (meaning that they do not contain queries) */
sealed trait TermQuery extends Query {
// noop for everything except Query.Term
def mapLastTerm(f: Query.Term => Query): Query = this
}

/** A trait for a list of one or more queries */
final case class MultiQuery(qs: NonEmptyList[Query]) extends Query {

def mapLastTerm(f: Query.Term => Query): MultiQuery = {
Expand All @@ -50,22 +54,60 @@ object MultiQuery {
}

object Query {

/** A term query
* e.g. 'cat', 'catch22'
*/
final case class Term(str: String) extends TermQuery {
override def mapLastTerm(f: Query.Term => Query): Query =
f(this)
}

/** A phrase query
* e.g. 'the cat jumped'
*/
final case class Phrase(str: String) extends TermQuery

/** A prefix query
* Search for words starting with the given prefix
* e.g. 'jump*'
*/
final case class Prefix(str: String) extends TermQuery

/** A proximity query
* Search for words within a specified word distance
* e.g. '"cat jumped"~3', '"one two three"~2'
*/
final case class Proximity(str: String, num: Int) extends TermQuery

/** A fuzzy query
* Search for words within a Damerau-Levenshtein Distance
* The additional parameter, between 0 and 2, specifies the number of edits allowed (defaults to 2)
* e.g. 'cat~', 'cat~1'
*/
final case class Fuzzy(str: String, num: Option[Int]) extends TermQuery

/** A regex query
* Search with a regular expression, the pattern is given between forward slashes, `/`.
* e.g. '/.ump(s|ing)'
*/
final case class TermRegex(str: String) extends TermQuery

/** A range query
* Search for terms that fall between some upper and lower bounds. The bounds can be inclusive or exclusive.
* e.g. '{cats TO dogs}', '[1 TO *]'
*/
final case class TermRange(
lower: Option[String],
upper: Option[String],
lowerInc: Boolean,
upperInc: Boolean,
) extends TermQuery

/** An Or operator
* Join the given queries with OR, the equivalent of taking the union of the results of each query
* e.g. 'q1 OR q2'
*/
final case class Or(qs: NonEmptyList[Query]) extends Query {
def mapLastTerm(f: Query.Term => Query): Or =
Or(rewriteLastTerm(qs, f))
Expand All @@ -75,6 +117,10 @@ object Query {
Or(NonEmptyList(head, tail.toList))
}

/** An And operator
* Join the given queries with AND, the equivalent of taking the intersection of the results of each query
* e.g. 'q1 AND q2'
*/
final case class And(qs: NonEmptyList[Query]) extends Query {
def mapLastTerm(f: Query.Term => Query): And =
And(rewriteLastTerm(qs, f))
Expand All @@ -84,11 +130,19 @@ object Query {
And(NonEmptyList(head, tail.toList))
}

/** A Not operator
* Exclude terms that would match the given query
* e.g. 'NOT cats'
*/
final case class Not(q: Query) extends Query {
def mapLastTerm(f: Query.Term => Query): Not =
Not(q.mapLastTerm(f))
}

/** A group query
* Queries grouped together with parentheses
* e.g. '(cats AND dogs)'
*/
final case class Group(qs: NonEmptyList[Query]) extends Query {
def mapLastTerm(f: Query.Term => Query): Group = this
}
Expand All @@ -97,17 +151,36 @@ object Query {
Group(NonEmptyList(head, tail.toList))
}

/** A unary plus query
* Search for documents which must contain the given query
* e.g. '+cat', '+(cats AND dogs)'
*/
final case class UnaryPlus(q: Query) extends Query {
def mapLastTerm(f: Query.Term => Query): UnaryPlus =
UnaryPlus(q.mapLastTerm(f))
}

/** A unary minus query
* Search for documents which must not contain the given query
* e.g. '-cat', '-(cats AND dogs)'
*/
final case class UnaryMinus(q: Query) extends Query {
def mapLastTerm(f: Query.Term => Query): UnaryMinus =
UnaryMinus(q.mapLastTerm(f))
}

/** A minimum match query
* Search for documents that match at least `num` of the given queries
* e.g. '(one two three)@2'
*/
final case class MinimumMatch(qs: NonEmptyList[Query], num: Int) extends Query {
def mapLastTerm(f: Query.Term => Query): MinimumMatch = this
}

/** A field query
* Search for documents by applying the given query only to the named field
* e.g. 'author:"Silly Goose"', 'title:(cats AND dogs)'
*/
final case class Field(field: String, q: Query) extends Query {
def mapLastTerm(f: Query.Term => Query): Field =
Field(field, q.mapLastTerm(f))
Expand Down

0 comments on commit e75f1d3

Please sign in to comment.