dovecot-2.1: fts-lucene: Fixed search when all terms were MUST_NOT.
dovecot at dovecot.org
dovecot at dovecot.org
Fri Nov 25 04:25:21 EET 2011
details: http://hg.dovecot.org/dovecot-2.1/rev/1753a762b56f
changeset: 13786:1753a762b56f
user: Timo Sirainen <tss at iki.fi>
date: Fri Nov 25 04:25:09 2011 +0200
description:
fts-lucene: Fixed search when all terms were MUST_NOT.
diffstat:
src/plugins/fts-lucene/lucene-wrapper.cc | 92 ++++++++++++++++++++++++--------
1 files changed, 69 insertions(+), 23 deletions(-)
diffs (205 lines):
diff -r 8c8dd04b8496 -r 1753a762b56f src/plugins/fts-lucene/lucene-wrapper.cc
--- a/src/plugins/fts-lucene/lucene-wrapper.cc Thu Nov 24 21:27:19 2011 +0200
+++ b/src/plugins/fts-lucene/lucene-wrapper.cc Fri Nov 25 04:25:09 2011 +0200
@@ -39,6 +39,12 @@
using namespace lucene::analysis;
using namespace lucene::util;
+struct lucene_query {
+ Query *query;
+ BooleanClause::Occur occur;
+};
+ARRAY_DEFINE_TYPE(lucene_query, struct lucene_query);
+
struct lucene_analyzer {
char *lang;
Analyzer *analyzer;
@@ -1049,7 +1055,8 @@
}
static bool
-lucene_add_definite_query(struct lucene_index *index, BooleanQuery &query,
+lucene_add_definite_query(struct lucene_index *index,
+ ARRAY_TYPE(lucene_query) &queries,
struct mail_search_arg *arg, bool and_args)
{
Query *q;
@@ -1099,22 +1106,26 @@
a stop word) */
return false;
}
+
+ struct lucene_query *lq = array_append_space(&queries);
+ lq->query = q;
if (!and_args)
- query.add(q, true, BooleanClause::SHOULD);
+ lq->occur = BooleanClause::SHOULD;
else if (!arg->match_not)
- query.add(q, true, BooleanClause::MUST);
+ lq->occur = BooleanClause::MUST;
else
- query.add(q, true, BooleanClause::MUST_NOT);
+ lq->occur = BooleanClause::MUST_NOT;
return true;
}
static bool
-lucene_add_maybe_query(struct lucene_index *index, BooleanQuery &query,
+lucene_add_maybe_query(struct lucene_index *index,
+ ARRAY_TYPE(lucene_query) &queries,
struct mail_search_arg *arg, bool and_args)
{
Query *q = NULL;
- if (arg->match_not && !and_args) {
+ if (arg->match_not) {
/* FIXME: we could handle this by doing multiple queries.. */
return false;
}
@@ -1146,25 +1157,56 @@
a stop word) */
return false;
}
+ struct lucene_query *lq = array_append_space(&queries);
+ lq->query = q;
if (!and_args)
- query.add(q, true, BooleanClause::SHOULD);
+ lq->occur = BooleanClause::SHOULD;
else if (!arg->match_not)
- query.add(q, true, BooleanClause::MUST);
+ lq->occur = BooleanClause::MUST;
else
- query.add(q, true, BooleanClause::MUST_NOT);
+ lq->occur = BooleanClause::MUST_NOT;
return true;
+ return true;
+}
+
+static bool queries_have_non_must_nots(ARRAY_TYPE(lucene_query) &queries)
+{
+ const struct lucene_query *lq;
+
+ array_foreach(&queries, lq) {
+ if (lq->occur != BooleanClause::MUST_NOT)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void search_query_add(BooleanQuery &query,
+ ARRAY_TYPE(lucene_query) &queries)
+{
+ BooleanQuery *search_query = _CLNEW BooleanQuery();
+ const struct lucene_query *lq;
+
+ if (queries_have_non_must_nots(queries)) {
+ array_foreach(&queries, lq)
+ search_query->add(lq->query, true, lq->occur);
+ query.add(search_query, true, BooleanClause::MUST);
+ } else {
+ array_foreach(&queries, lq)
+ search_query->add(lq->query, true, BooleanClause::SHOULD);
+ query.add(search_query, true, BooleanClause::MUST_NOT);
+ }
}
static int
lucene_index_search(struct lucene_index *index,
- Query &search_query, struct fts_result *result,
- ARRAY_TYPE(seq_range) *uids_r)
+ ARRAY_TYPE(lucene_query) &queries,
+ struct fts_result *result, ARRAY_TYPE(seq_range) *uids_r)
{
struct fts_score_map *score;
int ret = 0;
BooleanQuery query;
- query.add(&search_query, BooleanClause::MUST);
+ search_query_add(query, queries);
Term mailbox_term(_T("box"), index->mailbox_guid);
TermQuery mailbox_query(&mailbox_term);
@@ -1214,34 +1256,36 @@
if (lucene_index_open_search(index) <= 0)
return -1;
- BooleanQuery def_query;
+ ARRAY_TYPE(lucene_query) def_queries;
+ t_array_init(&def_queries, 16);
bool have_definites = false;
for (arg = args; arg != NULL; arg = arg->next) {
- if (lucene_add_definite_query(index, def_query, arg, and_args)) {
+ if (lucene_add_definite_query(index, def_queries, arg, and_args)) {
arg->match_always = true;
have_definites = true;
}
}
if (have_definites) {
- if (lucene_index_search(index, def_query, result,
+ if (lucene_index_search(index, def_queries, result,
&result->definite_uids) < 0)
return -1;
}
- BooleanQuery maybe_query;
+ ARRAY_TYPE(lucene_query) maybe_queries;
+ t_array_init(&maybe_queries, 16);
bool have_maybies = false;
for (arg = args; arg != NULL; arg = arg->next) {
- if (lucene_add_maybe_query(index, maybe_query, arg, and_args)) {
+ if (lucene_add_maybe_query(index, maybe_queries, arg, and_args)) {
arg->match_always = true;
have_maybies = true;
}
}
if (have_maybies) {
- if (lucene_index_search(index, maybe_query, NULL,
+ if (lucene_index_search(index, maybe_queries, NULL,
&result->maybe_uids) < 0)
return -1;
}
@@ -1250,13 +1294,14 @@
static int
lucene_index_search_multi(struct lucene_index *index, struct hash_table *guids,
- Query &search_query, struct fts_multi_result *result)
+ ARRAY_TYPE(lucene_query) &queries,
+ struct fts_multi_result *result)
{
struct fts_score_map *score;
int ret = 0;
BooleanQuery query;
- query.add(&search_query, BooleanClause::MUST);
+ search_query_add(query, queries);
BooleanQuery mailbox_query;
struct hash_iterate_context *iter;
@@ -1324,11 +1369,12 @@
if (lucene_index_open_search(index) <= 0)
return -1;
- BooleanQuery def_query;
+ ARRAY_TYPE(lucene_query) def_queries;
+ t_array_init(&def_queries, 16);
bool have_definites = false;
for (arg = args; arg != NULL; arg = arg->next) {
- if (lucene_add_definite_query(index, def_query, arg, and_args)) {
+ if (lucene_add_definite_query(index, def_queries, arg, and_args)) {
arg->match_always = true;
have_definites = true;
}
@@ -1336,7 +1382,7 @@
if (have_definites) {
if (lucene_index_search_multi(index, guids,
- def_query, result) < 0)
+ def_queries, result) < 0)
return -1;
}
return 0;
More information about the dovecot-cvs
mailing list