check for and forbid pure negative query

This commit is contained in:
dockes 2006-04-07 13:10:22 +00:00
parent ab905355b6
commit b955f42655
2 changed files with 51 additions and 25 deletions

View File

@ -27,6 +27,7 @@
*****************************************************************************/
#include <qfiledialog.h>
#include <qmessagebox.h>
#include <list>
#include <string>
@ -127,11 +128,23 @@ void advsearch::restrictFtCB_toggled(bool on)
void advsearch::searchPB_clicked()
{
Rcl::AdvSearchData mydata;
mydata.allwords = string((const char*)(andWordsLE->text().utf8()));
mydata.phrase = string((const char*)(phraseLE->text().utf8()));
mydata.orwords = string((const char*)(orWordsLE->text().utf8()));
mydata.nowords = string((const char*)(noWordsLE->text().utf8()));
mydata.filename = string((const char*)(fileNameLE->text().utf8()));
if (mydata.allwords.empty() && mydata.phrase.empty() &&
mydata.orwords.empty() && mydata.filename.empty()) {
if (mydata.nowords.empty())
return;
QMessageBox::warning(0, "Recoll",
tr("Cannot execute pure negative query. "
"Please enter common terms in the 'any words' field"));
return;
}
if (restrictFtCB->isOn() && noFiltypsLB->count() > 0) {
for (unsigned int i = 0; i < yesFiltypsLB->count(); i++) {
QCString ctext = yesFiltypsLB->item(i)->text().utf8();

View File

@ -1,5 +1,5 @@
#ifndef lint
static char rcsid[] = "@(#$Id: rcldb.cpp,v 1.62 2006-04-05 13:39:07 dockes Exp $ (C) 2004 J.F.Dockes";
static char rcsid[] = "@(#$Id: rcldb.cpp,v 1.63 2006-04-07 13:10:22 dockes Exp $ (C) 2004 J.F.Dockes";
#endif
/*
* This program is free software; you can redistribute it and/or modify
@ -545,13 +545,6 @@ bool Db::add(const string &fn, const Doc &idoc,
// Mime type
newdocument.add_term("T" + doc.mimetype);
// Path name term. This is used for existence/uptodate checks
string hash;
pathHash(fn, hash, PATHHASHLEN);
LOGDEB2(("Db::add: pathhash [%s]\n", hash.c_str()));
string pathterm = "P" + hash;
newdocument.add_term(pathterm);
// Simple file name. This is used for file name searches only. We index
// it with a term prefix. utf8fn used to be the full path, but it's now
// the simple file name.
@ -560,10 +553,23 @@ bool Db::add(const string &fn, const Doc &idoc,
newdocument.add_term(noacc);
}
// Internal path: with path, makes unique identifier for documents
// Pathname/ipath terms. This is used for file existence/uptodate
// checks, and unique id for the replace_document() call
// Truncate the filepath part to a reasonable length and
// replace the truncated part with a hopefully unique hash
string hash;
pathHash(fn, hash, PATHHASHLEN);
LOGDEB2(("Db::add: pathhash [%s]\n", hash.c_str()));
string pathterm = "P" + hash;
newdocument.add_term(pathterm);
// Unique term: with path, makes unique identifier for documents
// inside multidocument files.
string uniterm;
if (!doc.ipath.empty()) {
if (doc.ipath.empty()) {
uniterm = pathterm;
} else {
uniterm = "Q" + hash + "|" + doc.ipath;
newdocument.add_term(uniterm);
}
@ -617,8 +623,7 @@ bool Db::add(const string &fn, const Doc &idoc,
// Add db entry or update existing entry:
try {
Xapian::docid did =
m_ndb->wdb.replace_document(uniterm.empty() ? pathterm : uniterm,
newdocument);
m_ndb->wdb.replace_document(uniterm, newdocument);
if (did < m_ndb->updated.size()) {
m_ndb->updated[did] = true;
LOGDEB(("Db::add: docid %d updated [%s , %s]\n", did, fnc,
@ -1216,19 +1221,6 @@ bool Db::setQuery(AdvSearchData &sdata, QueryOpts opts,
}
}
// We do no stem expansion on 'No' words. Should we ?
if (!sdata.nowords.empty()) {
stringToXapianQueries(sdata.nowords, stemlang, m_ndb, pqueries);
if (!pqueries.empty()) {
Xapian::Query nq;
nq = Xapian::Query(Xapian::Query::OP_OR, pqueries.begin(),
pqueries.end());
xq = xq.empty() ? nq :
Xapian::Query(Xapian::Query::OP_AND_NOT, xq, nq);
pqueries.clear();
}
}
if (!sdata.phrase.empty()) {
Xapian::Query nq;
string s = string("\"") + sdata.phrase + string("\"");
@ -1253,6 +1245,27 @@ bool Db::setQuery(AdvSearchData &sdata, QueryOpts opts,
xq = xq.empty() ? tq : Xapian::Query(Xapian::Query::OP_FILTER, xq, tq);
}
// "And not" part. Must come last, as we have to check it's not
// the only term in the query. We do no stem expansion on 'No'
// words. Should we ?
if (!sdata.nowords.empty()) {
stringToXapianQueries(sdata.nowords, stemlang, m_ndb, pqueries);
if (!pqueries.empty()) {
Xapian::Query nq;
nq = Xapian::Query(Xapian::Query::OP_OR, pqueries.begin(),
pqueries.end());
if (xq.empty()) {
// Xapian cant do this currently. Have to have a positive
// part!
sdata.description = "Error: pure negative query\n";
LOGERR(("Rcl::Db::setQuery: error: pure negative query\n"));
return false;
}
xq = Xapian::Query(Xapian::Query::OP_AND_NOT, xq, nq);
pqueries.clear();
}
}
m_ndb->query = xq;
delete m_ndb->enquire;
m_ndb->enquire = new Xapian::Enquire(m_ndb->db);