From 7ccd9ffcce93cdaafeca723e6c6dc36e65c3e025 Mon Sep 17 00:00:00 2001 From: Veloman Yunkan Date: Mon, 12 Apr 2021 12:29:06 +0400 Subject: [PATCH] Catalog filtering by language works via Xapian --- include/library.h | 3 +++ src/library.cpp | 17 ++++++++++++++++- test/library.cpp | 13 +++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/include/library.h b/include/library.h index f49e7dfd1..6a2c79d23 100644 --- a/include/library.h +++ b/include/library.h @@ -117,6 +117,9 @@ class Filter { bool hasCategory() const; const std::string& getCategory() const { return _category; } + bool hasLang() const; + const std::string& getLang() const { return _lang; } + private: friend class Library; diff --git a/src/library.cpp b/src/library.cpp index 89a2eb31e..230206674 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -284,12 +284,14 @@ void Library::updateBookDB(const Book& book) doc.add_value(1, desc); doc.add_value(2, name); doc.add_value(3, category); + doc.add_value(4, lang); doc.set_data(book.getId()); indexer.index_text(title, 1, "S"); indexer.index_text(desc, 1, "XD"); indexer.index_text(name, 1, "XN"); indexer.index_text(category, 1, "XC"); + indexer.index_text(lang, 1, "L"); // Index fields without prefixes for general search indexer.index_text(title); @@ -324,6 +326,7 @@ Xapian::Query buildXapianQueryFromFilterQuery(const Filter& filter) queryParser.add_prefix("description", "XD"); queryParser.add_prefix("name", "XN"); queryParser.add_prefix("category", "XC"); + queryParser.add_prefix("lang", "L"); const auto partialQueryFlag = filter.queryIsPartial() ? Xapian::QueryParser::FLAG_PARTIAL : 0; @@ -349,6 +352,11 @@ Xapian::Query categoryQuery(const std::string& category) return Xapian::Query("XC" + category); } +Xapian::Query langQuery(const std::string& lang) +{ + return Xapian::Query("L" + lang); +} + Xapian::Query buildXapianQuery(const Filter& filter) { auto q = buildXapianQueryFromFilterQuery(filter); @@ -358,6 +366,9 @@ Xapian::Query buildXapianQuery(const Filter& filter) if ( filter.hasCategory() ) { q = Xapian::Query(Xapian::Query::OP_AND, q, categoryQuery(filter.getCategory())); } + if ( filter.hasLang() ) { + q = Xapian::Query(Xapian::Query::OP_AND, q, langQuery(filter.getLang())); + } return q; } @@ -660,6 +671,11 @@ bool Filter::hasCategory() const return ACTIVE(CATEGORY); } +bool Filter::hasLang() const +{ + return ACTIVE(LANG); +} + bool Filter::accept(const Book& book) const { auto local = !book.getPath().empty(); @@ -675,7 +691,6 @@ bool Filter::accept(const Book& book) const FILTER(_NOREMOTE, !remote) FILTER(MAXSIZE, book.getSize() <= _maxSize) - FILTER(LANG, book.getLanguage() == _lang) FILTER(_PUBLISHER, book.getPublisher() == _publisher) FILTER(_CREATOR, book.getCreator() == _creator) diff --git a/test/library.cpp b/test/library.cpp index 3dc84a3c7..02314699e 100644 --- a/test/library.cpp +++ b/test/library.cpp @@ -353,6 +353,19 @@ TEST_F(LibraryTest, filterByLanguage) "Ray Charles", "TED talks - Business" ); + + EXPECT_FILTER_RESULTS(kiwix::Filter().query("lang:eng"), + "Granblue Fantasy Wiki", + "Islam Stack Exchange", + "Movies & TV Stack Exchange", + "Mythology & Folklore Stack Exchange", + "Ray Charles", + "TED talks - Business" + ); + + EXPECT_FILTER_RESULTS(kiwix::Filter().query("eng"), + /* no results */ + ); } TEST_F(LibraryTest, filterByTags)