Catalog filtering by category works via Xapian

This commit is contained in:
Veloman Yunkan 2021-04-11 23:51:49 +04:00
parent 415c65cf03
commit 0c0a37073b
3 changed files with 29 additions and 1 deletions

View File

@ -114,6 +114,9 @@ class Filter {
bool hasName() const; bool hasName() const;
const std::string& getName() const { return _name; } const std::string& getName() const { return _name; }
bool hasCategory() const;
const std::string& getCategory() const { return _category; }
private: private:
friend class Library; friend class Library;

View File

@ -279,14 +279,17 @@ void Library::updateBookDB(const Book& book)
const std::string title = normalizeText(book.getTitle(), lang); const std::string title = normalizeText(book.getTitle(), lang);
const std::string desc = normalizeText(book.getDescription(), lang); const std::string desc = normalizeText(book.getDescription(), lang);
const std::string name = book.getName(); // this is supposed to be normalized const std::string name = book.getName(); // this is supposed to be normalized
const std::string category = book.getCategory(); // this is supposed to be normalized
doc.add_value(0, title); doc.add_value(0, title);
doc.add_value(1, desc); doc.add_value(1, desc);
doc.add_value(2, name); doc.add_value(2, name);
doc.add_value(3, category);
doc.set_data(book.getId()); doc.set_data(book.getId());
indexer.index_text(title, 1, "S"); indexer.index_text(title, 1, "S");
indexer.index_text(desc, 1, "XD"); indexer.index_text(desc, 1, "XD");
indexer.index_text(name, 1, "XN"); indexer.index_text(name, 1, "XN");
indexer.index_text(category, 1, "XC");
// Index fields without prefixes for general search // Index fields without prefixes for general search
indexer.index_text(title); indexer.index_text(title);
@ -320,6 +323,7 @@ Xapian::Query buildXapianQueryFromFilterQuery(const Filter& filter)
queryParser.add_prefix("title", "S"); queryParser.add_prefix("title", "S");
queryParser.add_prefix("description", "XD"); queryParser.add_prefix("description", "XD");
queryParser.add_prefix("name", "XN"); queryParser.add_prefix("name", "XN");
queryParser.add_prefix("category", "XC");
const auto partialQueryFlag = filter.queryIsPartial() const auto partialQueryFlag = filter.queryIsPartial()
? Xapian::QueryParser::FLAG_PARTIAL ? Xapian::QueryParser::FLAG_PARTIAL
: 0; : 0;
@ -340,12 +344,20 @@ Xapian::Query nameQuery(const std::string& name)
return Xapian::Query("XN" + name); return Xapian::Query("XN" + name);
} }
Xapian::Query categoryQuery(const std::string& category)
{
return Xapian::Query("XC" + category);
}
Xapian::Query buildXapianQuery(const Filter& filter) Xapian::Query buildXapianQuery(const Filter& filter)
{ {
auto q = buildXapianQueryFromFilterQuery(filter); auto q = buildXapianQueryFromFilterQuery(filter);
if ( filter.hasName() ) { if ( filter.hasName() ) {
q = Xapian::Query(Xapian::Query::OP_AND, q, nameQuery(filter.getName())); q = Xapian::Query(Xapian::Query::OP_AND, q, nameQuery(filter.getName()));
} }
if ( filter.hasCategory() ) {
q = Xapian::Query(Xapian::Query::OP_AND, q, categoryQuery(filter.getCategory()));
}
return q; return q;
} }
@ -643,6 +655,11 @@ bool Filter::hasName() const
return ACTIVE(NAME); return ACTIVE(NAME);
} }
bool Filter::hasCategory() const
{
return ACTIVE(CATEGORY);
}
bool Filter::accept(const Book& book) const bool Filter::accept(const Book& book) const
{ {
auto local = !book.getPath().empty(); auto local = !book.getPath().empty();
@ -658,7 +675,6 @@ bool Filter::accept(const Book& book) const
FILTER(_NOREMOTE, !remote) FILTER(_NOREMOTE, !remote)
FILTER(MAXSIZE, book.getSize() <= _maxSize) FILTER(MAXSIZE, book.getSize() <= _maxSize)
FILTER(CATEGORY, book.getCategory() == _category)
FILTER(LANG, book.getLanguage() == _lang) FILTER(LANG, book.getLanguage() == _lang)
FILTER(_PUBLISHER, book.getPublisher() == _publisher) FILTER(_PUBLISHER, book.getPublisher() == _publisher)
FILTER(_CREATOR, book.getCreator() == _creator) FILTER(_CREATOR, book.getCreator() == _creator)

View File

@ -502,6 +502,15 @@ TEST_F(LibraryTest, filterByCategory)
"Géographie par Wikipédia", "Géographie par Wikipédia",
"Mathématiques" "Mathématiques"
); );
EXPECT_FILTER_RESULTS(kiwix::Filter().query("category:category_element_overrides_tags"),
"Géographie par Wikipédia",
"Mathématiques"
);
EXPECT_FILTER_RESULTS(kiwix::Filter().query("category_element_overrides_tags"),
/* no results */
);
} }
TEST_F(LibraryTest, filterByMaxSize) TEST_F(LibraryTest, filterByMaxSize)