Xapian::Database *db;
Xapian::Enquire *enquire;
Xapian::MSetIterator mset_iter;
- int curr_query;
- bool next_query:1;
+ Xapian::MSet m;
+ bool init:1;
+ bool main_query:1;
};
static int
{
struct fts_flatcurve_xapian_query_iter *iter;
iter = new fts_flatcurve_xapian_query_iter();
- iter->curr_query = -1;
- iter->next_query = TRUE;
+ iter->init = FALSE;
+ iter->main_query = TRUE;
iter->query = query;
iter->result = p_new(query->pool,
struct fts_flatcurve_xapian_query_result, 1);
if (iter->error != NULL)
return FALSE;
- Xapian::MSet m;
- Xapian::Query *q = NULL;
- if (iter->next_query) {
- iter->next_query = FALSE;
+ if (!iter->init) {
+ iter->init = TRUE;
- if (iter->curr_query == -1) {
+ Xapian::Query *q = NULL, maybe;
+ if (iter->main_query) {
if (iter->query->xapian->query == NULL)
- ++iter->curr_query;
+ iter->main_query = FALSE;
else
q = iter->query->xapian->query;
}
/* Maybe queries. */
- if ((iter->curr_query >= 0) &&
- (array_not_empty(&iter->query->xapian->maybe_queries)) &&
- (array_count(&iter->query->xapian->maybe_queries) > iter->curr_query)) {
+ if (!iter->main_query &&
+ array_not_empty(&iter->query->xapian->maybe_queries)) {
const struct flatcurve_fts_query_xapian_maybe *mquery;
- mquery = array_idx(&iter->query->xapian->maybe_queries,
- iter->curr_query);
- q = mquery->query;
+ maybe = Xapian::Query();
+ array_foreach(&iter->query->xapian->maybe_queries, mquery)
+ maybe = Xapian::Query(Xapian::Query::OP_OR, maybe,
+ *mquery->query);
+ /* Add main query to merge Xapian scores correctly. */
+ if (iter->query->xapian->query != NULL)
+ maybe = Xapian::Query(Xapian::Query::OP_AND_MAYBE, maybe,
+ *iter->query->xapian->query);
+ q = &maybe;
}
if (q == NULL)
iter->enquire->set_query(*q);
try {
- m = iter->enquire->get_mset(0, iter->db->get_doccount());
+ iter->m = iter->enquire->get_mset(0, iter->db->get_doccount());
} catch (Xapian::DatabaseModifiedError &e) {
/* Per documentation, this is only thrown if more than
* one change has been made to the database. To
i_unreached();
}
- iter->mset_iter = m.begin();
+ iter->mset_iter = iter->m.begin();
}
- if (iter->mset_iter == m.end()) {
- ++iter->curr_query;
- iter->next_query = TRUE;
+ if (iter->mset_iter == iter->m.end()) {
+ if (!iter->main_query)
+ return FALSE;
+ iter->init = iter->main_query = FALSE;
return fts_flatcurve_xapian_query_iter_next(iter, result_r);
}
- iter->result->maybe = (iter->curr_query >= 0);
+ iter->result->maybe = !iter->main_query;
iter->result->score = iter->mset_iter.get_weight();
/* MSet docid can be an "interleaved" docid generated by
* Xapian::Database when handling multiple DBs at once. Instead, we
iter = fts_flatcurve_xapian_query_iter_init(query);
while (fts_flatcurve_xapian_query_iter_next(iter, &result)) {
- if (result->maybe || query->xapian->maybe)
+ bool add_score = TRUE;
+ if (result->maybe || query->xapian->maybe) {
+ add_score = !seq_range_exists(&r->uids, result->uid) &&
+ !seq_range_exists(&r->maybe_uids, result->uid);
seq_range_array_add(&r->maybe_uids, result->uid);
- else
+ } else
seq_range_array_add(&r->uids, result->uid);
- score = array_append_space(&r->scores);
- score->score = (float)result->score;
- score->uid = result->uid;
+ if (add_score) {
+ score = array_append_space(&r->scores);
+ score->score = (float)result->score;
+ score->uid = result->uid;
+ }
}
return fts_flatcurve_xapian_query_iter_deinit(&iter, error_r);
}