mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-06 15:15:58 +00:00
Flatten nested and/or queries
This commit is contained in:
parent
63d146c2de
commit
7638dc5111
@ -1,5 +1,7 @@
|
|||||||
package docspell.query.internal
|
package docspell.query.internal
|
||||||
|
|
||||||
|
import cats.data.{NonEmptyList => Nel}
|
||||||
|
|
||||||
import docspell.query.ItemQuery.Expr._
|
import docspell.query.ItemQuery.Expr._
|
||||||
import docspell.query.ItemQuery._
|
import docspell.query.ItemQuery._
|
||||||
|
|
||||||
@ -11,12 +13,14 @@ object ExprUtil {
|
|||||||
def reduce(expr: Expr): Expr =
|
def reduce(expr: Expr): Expr =
|
||||||
expr match {
|
expr match {
|
||||||
case AndExpr(inner) =>
|
case AndExpr(inner) =>
|
||||||
if (inner.tail.isEmpty) reduce(inner.head)
|
val nodes = spliceAnd(inner)
|
||||||
else AndExpr(inner.map(reduce))
|
if (nodes.tail.isEmpty) reduce(nodes.head)
|
||||||
|
else AndExpr(nodes.map(reduce))
|
||||||
|
|
||||||
case OrExpr(inner) =>
|
case OrExpr(inner) =>
|
||||||
if (inner.tail.isEmpty) reduce(inner.head)
|
val nodes = spliceOr(inner)
|
||||||
else OrExpr(inner.map(reduce))
|
if (nodes.tail.isEmpty) reduce(nodes.head)
|
||||||
|
else OrExpr(nodes.map(reduce))
|
||||||
|
|
||||||
case NotExpr(inner) =>
|
case NotExpr(inner) =>
|
||||||
inner match {
|
inner match {
|
||||||
@ -62,4 +66,19 @@ object ExprUtil {
|
|||||||
case CustomFieldIdMatch(_, _, _) =>
|
case CustomFieldIdMatch(_, _, _) =>
|
||||||
expr
|
expr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def spliceAnd(nodes: Nel[Expr]): Nel[Expr] =
|
||||||
|
nodes.flatMap {
|
||||||
|
case Expr.AndExpr(inner) =>
|
||||||
|
spliceAnd(inner)
|
||||||
|
case node =>
|
||||||
|
Nel.of(node)
|
||||||
|
}
|
||||||
|
private def spliceOr(nodes: Nel[Expr]): Nel[Expr] =
|
||||||
|
nodes.flatMap {
|
||||||
|
case Expr.OrExpr(inner) =>
|
||||||
|
spliceOr(inner)
|
||||||
|
case node =>
|
||||||
|
Nel.of(node)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,6 @@ class FulltextExtractTest extends FunSuite {
|
|||||||
|
|
||||||
test("wrong fulltext search position") {
|
test("wrong fulltext search position") {
|
||||||
assertFts("name:test (| date:2021-02 content:yes)", Result.UnsupportedPosition)
|
assertFts("name:test (| date:2021-02 content:yes)", Result.UnsupportedPosition)
|
||||||
assertFts("name:test (& date:2021-02 content:yes)", Result.UnsupportedPosition) //TODO
|
assertFtsSuccess("name:test (& date:2021-02 content:yes)", "yes".some)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package docspell.query.internal
|
package docspell.query.internal
|
||||||
|
|
||||||
|
import cats.implicits._
|
||||||
|
|
||||||
import munit._
|
import munit._
|
||||||
import docspell.query.ItemQueryParser
|
import docspell.query.ItemQueryParser
|
||||||
import docspell.query.ItemQuery
|
import docspell.query.ItemQuery
|
||||||
@ -40,4 +42,20 @@ class ItemQueryParserTest extends FunSuite {
|
|||||||
val q = ItemQueryParser.parseUnsafe("")
|
val q = ItemQueryParser.parseUnsafe("")
|
||||||
assertEquals(ItemQuery.all, q)
|
assertEquals(ItemQuery.all, q)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("splice inner and nodes") {
|
||||||
|
val raw = "(& name:hello (& date:2021-02 name:world) (& name:hello) )"
|
||||||
|
val q = ItemQueryParser.parseUnsafe(raw)
|
||||||
|
val expect =
|
||||||
|
ItemQueryParser.parseUnsafe("name:hello date:2021-02 name:world name:hello")
|
||||||
|
assertEquals(expect.copy(raw = raw.some), q)
|
||||||
|
}
|
||||||
|
|
||||||
|
test("splice inner or nodes") {
|
||||||
|
val raw = "(| name:hello (| date:2021-02 name:world) (| name:hello) )"
|
||||||
|
val q = ItemQueryParser.parseUnsafe(raw)
|
||||||
|
val expect =
|
||||||
|
ItemQueryParser.parseUnsafe("(| name:hello date:2021-02 name:world name:hello )")
|
||||||
|
assertEquals(expect.copy(raw = raw.some), q)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user