mirror of https://github.com/kiwix/libkiwix.git
Catalog filtering by book name works via Xapian
This commit is contained in:
parent
8287f351e7
commit
415c65cf03
|
@ -111,6 +111,9 @@ class Filter {
|
||||||
const std::string& getQuery() const { return _query; }
|
const std::string& getQuery() const { return _query; }
|
||||||
bool queryIsPartial() const { return _queryIsPartial; }
|
bool queryIsPartial() const { return _queryIsPartial; }
|
||||||
|
|
||||||
|
bool hasName() const;
|
||||||
|
const std::string& getName() const { return _name; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Library;
|
friend class Library;
|
||||||
|
|
||||||
|
|
|
@ -278,12 +278,15 @@ 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
|
||||||
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.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");
|
||||||
|
|
||||||
// Index fields without prefixes for general search
|
// Index fields without prefixes for general search
|
||||||
indexer.index_text(title);
|
indexer.index_text(title);
|
||||||
|
@ -303,7 +306,8 @@ bool willSelectEverything(const Xapian::Query& query)
|
||||||
return query.get_type() == Xapian::Query::LEAF_MATCH_ALL;
|
return query.get_type() == Xapian::Query::LEAF_MATCH_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Xapian::Query buildXapianQuery(const Filter& filter)
|
|
||||||
|
Xapian::Query buildXapianQueryFromFilterQuery(const Filter& filter)
|
||||||
{
|
{
|
||||||
if ( !filter.hasQuery() ) {
|
if ( !filter.hasQuery() ) {
|
||||||
// This is a thread-safe way to construct an equivalent of
|
// This is a thread-safe way to construct an equivalent of
|
||||||
|
@ -315,6 +319,7 @@ Xapian::Query buildXapianQuery(const Filter& filter)
|
||||||
queryParser.set_default_op(Xapian::Query::OP_AND);
|
queryParser.set_default_op(Xapian::Query::OP_AND);
|
||||||
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");
|
||||||
const auto partialQueryFlag = filter.queryIsPartial()
|
const auto partialQueryFlag = filter.queryIsPartial()
|
||||||
? Xapian::QueryParser::FLAG_PARTIAL
|
? Xapian::QueryParser::FLAG_PARTIAL
|
||||||
: 0;
|
: 0;
|
||||||
|
@ -330,6 +335,20 @@ Xapian::Query buildXapianQuery(const Filter& filter)
|
||||||
return queryParser.parse_query(filter.getQuery(), flags);
|
return queryParser.parse_query(filter.getQuery(), flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Xapian::Query nameQuery(const std::string& name)
|
||||||
|
{
|
||||||
|
return Xapian::Query("XN" + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Xapian::Query buildXapianQuery(const Filter& filter)
|
||||||
|
{
|
||||||
|
auto q = buildXapianQueryFromFilterQuery(filter);
|
||||||
|
if ( filter.hasName() ) {
|
||||||
|
q = Xapian::Query(Xapian::Query::OP_AND, q, nameQuery(filter.getName()));
|
||||||
|
}
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
Library::BookIdCollection Library::filterViaBookDB(const Filter& filter)
|
Library::BookIdCollection Library::filterViaBookDB(const Filter& filter)
|
||||||
|
@ -619,6 +638,11 @@ bool Filter::hasQuery() const
|
||||||
return ACTIVE(QUERY);
|
return ACTIVE(QUERY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Filter::hasName() const
|
||||||
|
{
|
||||||
|
return ACTIVE(NAME);
|
||||||
|
}
|
||||||
|
|
||||||
bool Filter::accept(const Book& book) const
|
bool Filter::accept(const Book& book) const
|
||||||
{
|
{
|
||||||
auto local = !book.getPath().empty();
|
auto local = !book.getPath().empty();
|
||||||
|
@ -638,7 +662,6 @@ bool Filter::accept(const Book& book) const
|
||||||
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)
|
||||||
FILTER(NAME, book.getName() == _name)
|
|
||||||
|
|
||||||
if (ACTIVE(ACCEPTTAGS)) {
|
if (ACTIVE(ACCEPTTAGS)) {
|
||||||
if (!_acceptTags.empty()) {
|
if (!_acceptTags.empty()) {
|
||||||
|
|
|
@ -486,6 +486,14 @@ TEST_F(LibraryTest, filterByName)
|
||||||
EXPECT_FILTER_RESULTS(kiwix::Filter().name("wikibooks_de"),
|
EXPECT_FILTER_RESULTS(kiwix::Filter().name("wikibooks_de"),
|
||||||
"An example ZIM archive"
|
"An example ZIM archive"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
EXPECT_FILTER_RESULTS(kiwix::Filter().query("name:wikibooks_de"),
|
||||||
|
"An example ZIM archive"
|
||||||
|
);
|
||||||
|
|
||||||
|
EXPECT_FILTER_RESULTS(kiwix::Filter().query("wikibooks_de"),
|
||||||
|
/* no results */
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(LibraryTest, filterByCategory)
|
TEST_F(LibraryTest, filterByCategory)
|
||||||
|
|
Loading…
Reference in New Issue