diff --git a/modules/store/src/main/scala/docspell/store/queries/QItem.scala b/modules/store/src/main/scala/docspell/store/queries/QItem.scala index b4ca2472..3ce1af55 100644 --- a/modules/store/src/main/scala/docspell/store/queries/QItem.scala +++ b/modules/store/src/main/scala/docspell/store/queries/QItem.scala @@ -250,14 +250,22 @@ object QItem { .innerJoin(tag, tag.tid === ti.tagId) .innerJoin(i, i.id === ti.itemId) - findItemsBase(q, 0).unwrap - .withSelect(select(tag.all).append(count(i.id).as("num"))) - .changeFrom(_.prepend(tagFrom)) - .changeWhere(c => c && queryCondition(q)) - .groupBy(tag.tid) - .build - .query[TagCount] - .to[List] + val tagCloud = + findItemsBase(q, 0).unwrap + .withSelect(select(tag.all).append(count(i.id).as("num"))) + .changeFrom(_.prepend(tagFrom)) + .changeWhere(c => c && queryCondition(q)) + .groupBy(tag.tid) + .build + .query[TagCount] + .to[List] + + // the previous query starts from tags, so items with tag-count=0 + // are not included they are fetched separately + for { + existing <- tagCloud + other <- RTag.findOthers(q.account.collective, existing.map(_.tag.tagId)) + } yield existing ++ other.map(TagCount(_, 0)) } def searchCountSummary(q: Query): ConnectionIO[Int] = diff --git a/modules/store/src/main/scala/docspell/store/records/RTag.scala b/modules/store/src/main/scala/docspell/store/records/RTag.scala index 9884a04d..27a30031 100644 --- a/modules/store/src/main/scala/docspell/store/records/RTag.scala +++ b/modules/store/src/main/scala/docspell/store/records/RTag.scala @@ -135,6 +135,19 @@ object RTag { } } + def findOthers(coll: Ident, excludeTags: List[Ident]): ConnectionIO[List[RTag]] = { + val excl = + NonEmptyList + .fromList(excludeTags) + .map(nel => T.tid.notIn(nel)) + + Select( + select(T.all), + from(T), + T.cid === coll &&? excl + ).orderBy(T.name.asc).build.query[RTag].to[List] + } + def delete(tagId: Ident, coll: Ident): ConnectionIO[Int] = DML.delete(T, T.tid === tagId && T.cid === coll) }