Ticket #203: multweight.patch
File multweight.patch, 22.9 KB (added by , 17 years ago) |
---|
-
xapian-core/matcher/multweightpostlist.cc
1 /** @file multweightpostlist.cc 2 * @brief Return documents from a subquery with weights multiplied by a double. 3 */ 4 /* Copyright 2007 Lemur Consulting Ltd 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #include <config.h> 22 23 #include "omassert.h" 24 #include "multweightpostlist.h" 25 26 // Include branchpostlist for utility functions "next_handling_prune" and 27 // "skip_to_handling_prune" 28 #include "branchpostlist.h" 29 30 Xapian::doccount 31 MultWeightPostList::get_termfreq_min() const 32 { 33 return source->get_termfreq_min(); 34 } 35 36 Xapian::doccount 37 MultWeightPostList::get_termfreq_est() const 38 { 39 return source->get_termfreq_est(); 40 } 41 42 Xapian::doccount 43 MultWeightPostList::get_termfreq_max() const 44 { 45 return source->get_termfreq_max(); 46 } 47 48 Xapian::weight 49 MultWeightPostList::get_maxweight() const 50 { 51 return source->get_maxweight() * multiplier; 52 } 53 54 Xapian::docid 55 MultWeightPostList::get_docid() const 56 { 57 return source->get_docid(); 58 } 59 60 Xapian::weight 61 MultWeightPostList::get_weight() const 62 { 63 return source->get_weight() * multiplier; 64 } 65 66 Xapian::doclength 67 MultWeightPostList::get_doclength() const 68 { 69 return source->get_doclength(); 70 } 71 72 Xapian::weight 73 MultWeightPostList::recalc_maxweight() 74 { 75 return source->recalc_maxweight() * multiplier; 76 } 77 78 PositionList * 79 MultWeightPostList::read_position_list() 80 { 81 return source->read_position_list(); 82 } 83 84 PositionList * 85 MultWeightPostList::open_position_list() const 86 { 87 return source->open_position_list(); 88 } 89 90 PostList * 91 MultWeightPostList::next(Xapian::weight w_min) 92 { 93 AssertNe(multiplier, 0); 94 next_handling_prune(source, w_min / multiplier, matcher); 95 return NULL; 96 } 97 98 PostList * 99 MultWeightPostList::skip_to(Xapian::docid did, Xapian::weight w_min) 100 { 101 AssertNe(multiplier, 0); 102 skip_to_handling_prune(source, did, w_min / multiplier, matcher); 103 return NULL; 104 } 105 106 bool 107 MultWeightPostList::at_end() const 108 { 109 return source->at_end(); 110 } 111 112 string 113 MultWeightPostList::get_description() const 114 { 115 string desc = "MultWeightPostList("; 116 desc += source->get_description(); 117 desc += " * "; 118 desc += om_tostring(multiplier); 119 desc += ")"; 120 return desc; 121 } -
xapian-core/matcher/multweightpostlist.h
Property changes on: xapian-core/matcher/multweightpostlist.cc ___________________________________________________________________ Name: svn:eol-style + native
1 /** @file multweightpostlist.h 2 * @brief Return documents from a subquery with weights multiplied by a double. 3 */ 4 /* Copyright 2007 Lemur Consulting Ltd 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #ifndef XAPIAN_INCLUDED_MULTWEIGHTPOSTLIST_H 22 #define XAPIAN_INCLUDED_MULTWEIGHTPOSTLIST_H 23 24 #include "database.h" 25 #include "postlist.h" 26 27 class MultiMatch; 28 29 class MultWeightPostList : public PostList { 30 /** The sub-postlist. */ 31 PostList *source; 32 33 /** The multiplier to apply to the weights. */ 34 double multiplier; 35 36 /** The object which is using this postlist to perform 37 * a match. This object needs to be notified when the 38 * tree changes such that the maximum weights need to be 39 * recalculated. 40 */ 41 MultiMatch *matcher; 42 43 /// Disallow copying. 44 MultWeightPostList(const MultWeightPostList &); 45 46 /// Disallow assignment. 47 void operator=(const MultWeightPostList &); 48 49 public: 50 MultWeightPostList(PostList *source_, double multiplier_, 51 MultiMatch *matcher_) 52 : source(source_), multiplier(multiplier_), matcher(matcher_) {} 53 ~MultWeightPostList() { delete source; } 54 55 Xapian::doccount get_termfreq_min() const; 56 Xapian::doccount get_termfreq_est() const; 57 Xapian::doccount get_termfreq_max() const; 58 Xapian::weight get_maxweight() const; 59 Xapian::docid get_docid() const; 60 Xapian::weight get_weight() const; 61 Xapian::doclength get_doclength() const; 62 Xapian::weight recalc_maxweight(); 63 PositionList * read_position_list(); 64 PositionList * open_position_list() const; 65 PostList * next(Xapian::weight w_min); 66 PostList * skip_to(Xapian::docid did, Xapian::weight w_min); 67 bool at_end() const; 68 string get_description() const; 69 }; 70 71 #endif /* XAPIAN_INCLUDED_MULTWEIGHTPOSTLIST_H */ -
xapian-core/matcher/Makefile.mk
Property changes on: xapian-core/matcher/multweightpostlist.h ___________________________________________________________________ Name: svn:eol-style + native
11 11 matcher/mergepostlist.h\ 12 12 matcher/msetcmp.h\ 13 13 matcher/msetpostlist.h\ 14 matcher/multweightpostlist.h\ 14 15 matcher/orpostlist.h\ 15 16 matcher/phrasepostlist.h\ 16 17 matcher/remotesubmatch.h\ … … 44 45 matcher/msetcmp.cc\ 45 46 matcher/msetpostlist.cc\ 46 47 matcher/multimatch.cc\ 48 matcher/multweightpostlist.cc\ 47 49 matcher/orpostlist.cc\ 48 50 matcher/phrasepostlist.cc\ 49 51 matcher/rset.cc\ -
xapian-core/matcher/localmatch.cc
3 3 * Copyright 1999,2000,2001 BrightStation PLC 4 4 * Copyright 2002 Ananova Ltd 5 5 * Copyright 2002,2003,2004,2005,2006,2007 Olly Betts 6 * Copyright 2007 Lemur Consulting Ltd 6 7 * 7 8 * This program is free software; you can redistribute it and/or 8 9 * modify it under the terms of the GNU General Public License as … … 38 39 #include "mergepostlist.h" 39 40 #include "extraweightpostlist.h" 40 41 #include "valuerangepostlist.h" 42 #include "multweightpostlist.h" 41 43 42 44 #include "omqueryinternal.h" 43 45 44 46 #include <algorithm> 45 47 #include "autoptr.h" 46 48 #include <queue> 49 #include <cfloat> 47 50 48 51 ///////////////////////////////////////////// 49 52 // Comparison operators which we will need // … … 476 479 case Xapian::Query::OP_VALUE_RANGE: 477 480 RETURN(new ValueRangePostList(db, Xapian::valueno(query->parameter), 478 481 query->tname, query->str_parameter)); 482 case Xapian::Query::OP_MULT_WEIGHT: 483 Assert(query->subqs.size() == 1); 484 if (is_bool || query->dbl_parameter < DBL_EPSILON) { 485 // Return as a boolean query. 486 RETURN(postlist_from_query(query->subqs[0], matcher, true)); 487 } else { 488 RETURN(new MultWeightPostList(postlist_from_query(query->subqs[0], matcher, is_bool), 489 query->dbl_parameter, matcher)); 490 } 479 491 } 480 492 Assert(false); 481 493 RETURN(NULL); -
xapian-core/tests/harness/testsuite.h
246 246 "Expected `"STRINGIZE(a)"' and `"STRINGIZE(b)"' to be (nearly) equal:" \ 247 247 " were " << setprecision(DBL_DIG) << (a) << " and " << (b) << ")" << setprecision(6)) 248 248 249 /// Test two doubles for non-near-equality. 250 #define TEST_NOT_EQUAL_DOUBLE(a, b) TEST_AND_EXPLAIN(!TEST_EQUAL_DOUBLE_((a), (b)), \ 251 "Expected `"STRINGIZE(a)"' and `"STRINGIZE(b)"' not to be (nearly) equal:" \ 252 " were " << setprecision(DBL_DIG) << (a) << " and " << (b) << ")" << setprecision(6)) 253 249 254 /// Test for non-equality of two things. 250 255 #define TEST_NOT_EQUAL(a, b) TEST_AND_EXPLAIN(((a) != (b)), \ 251 256 "Expected `"STRINGIZE(a)"' and `"STRINGIZE(b)"' not to be equal:" \ -
xapian-core/tests/harness/testsuite.cc
673 673 bool 674 674 TEST_EQUAL_DOUBLE_(double a, double b) 675 675 { 676 if (a == b) return true; 676 677 return (ceil(log10(max(fabs(a), fabs(b)))) - log10(fabs(a - b)) > DBL_DIG); 677 678 } -
xapian-core/tests/api_anydb.cc
1809 1809 return true; 1810 1810 } 1811 1811 1812 // Feature test for Query::OP_MULT_WEIGHT. 1813 static bool test_multweight1() { 1814 Xapian::Database db(get_database("apitest_phrase")); 1815 Xapian::Enquire enq(db); 1816 Xapian::QueryParser qp; 1817 1818 static const char * queries[] = { 1819 "pad", 1820 "milk fridge", 1821 "leave milk on fridge", 1822 "ordered milk operator", 1823 "ordered phrase operator", 1824 "leave \"milk on fridge\"", 1825 "notpresent", 1826 "leave \"milk notpresent\"", 1827 NULL 1828 }; 1829 static double multipliers[] = { 1830 -1000000, -2.5, -1, -0.5, 0, 0.5, 1, 2.5, 1000000, 1831 0, 0 1832 }; 1833 1834 for (const char **qstr = queries; *qstr; ++qstr) { 1835 Xapian::Query query1 = qp.parse_query(*qstr); 1836 tout << "query1: " << query1.get_description() << endl; 1837 for (double *multp = multipliers; multp[0] != multp[1]; ++multp) { 1838 double mult = *multp; 1839 Xapian::Query query2(Xapian::Query::OP_MULT_WEIGHT, query1, mult); 1840 tout << "query2: " << query2.get_description() << endl; 1841 1842 enq.set_query(query1); 1843 Xapian::MSet mset1 = enq.get_mset(0, 20); 1844 enq.set_query(query2); 1845 Xapian::MSet mset2 = enq.get_mset(0, 20); 1846 1847 TEST_EQUAL(mset1.size(), mset2.size()); 1848 1849 Xapian::MSetIterator i1, i2; 1850 if (mult > 0) { 1851 for (i1 = mset1.begin(), i2 = mset2.begin(); 1852 i1 != mset1.end() && i2 != mset2.end(); ++i1, ++i2) { 1853 TEST_EQUAL_DOUBLE(i1.get_weight() * mult, i2.get_weight()); 1854 TEST_EQUAL(*i1, *i2); 1855 } 1856 } else { 1857 // Weights in mset2 are 0; so it should be sorted by docid. 1858 vector<Xapian::docid> ids1; 1859 vector<Xapian::docid> ids2; 1860 for (i1 = mset1.begin(), i2 = mset2.begin(); 1861 i1 != mset1.end() && i2 != mset2.end(); ++i1, ++i2) { 1862 TEST_NOT_EQUAL_DOUBLE(i1.get_weight(), 0); 1863 TEST_EQUAL_DOUBLE(i2.get_weight(), 0); 1864 ids1.push_back(*i1); 1865 ids2.push_back(*i2); 1866 } 1867 sort(ids1.begin(), ids1.end()); 1868 TEST_EQUAL(ids1, ids2); 1869 } 1870 } 1871 } 1872 return true; 1873 } 1874 1812 1875 // ####################################################################### 1813 1876 // # End of test cases: now we list the tests to run. 1814 1877 … … 1875 1938 {"allpostlist1", test_allpostlist1}, 1876 1939 {"emptyterm1", test_emptyterm1}, 1877 1940 {"valuerange1", test_valuerange1}, 1941 {"multweight1", test_multweight1}, 1878 1942 {0, 0} 1879 1943 }; -
xapian-core/include/xapian/query.h
4 4 /* Copyright 1999,2000,2001 BrightStation PLC 5 5 * Copyright 2002 Ananova Ltd 6 6 * Copyright 2003,2004,2005,2006,2007 Olly Betts 7 * Copyright 2006 Lemur Consulting Ltd7 * Copyright 2006,2007 Lemur Consulting Ltd 8 8 * 9 9 * This program is free software; you can redistribute it and/or 10 10 * modify it under the terms of the GNU General Public License as … … 99 99 /** Select an elite set from the subqueries, and perform 100 100 * a query with these combined as an OR query. 101 101 */ 102 OP_ELITE_SET = 10 102 OP_ELITE_SET = 10, 103 104 /** Multiply the weight of a subquery by a multiplier. Only 105 * positive multiplers are supported - negative multipliers will be 106 * clipped to 0. */ 107 OP_MULT_WEIGHT 103 108 } op; 104 109 105 110 /** Copy constructor. */ … … 154 159 /** Apply the specified operator to a single Xapian::Query object. */ 155 160 Query(Query::op op_, Xapian::Query q); 156 161 162 /** Apply the specified operator to a single Xapian::Query object, with a parameter. */ 163 Query(Query::op op_, Xapian::Query q, double parameter); 164 157 165 /** Construct a value range query on a document value. 158 166 * 159 167 * A value range query matches those documents which have a value … … 281 289 /// Within query frequency of this term - leaf node only 282 290 Xapian::termcount wqf; 283 291 292 /// Used to store a multiplier for subquery weights. 293 double dbl_parameter; 294 284 295 /** swap the contents of this with another Xapian::Query::Internal, 285 296 * in a way which is guaranteed not to throw. This is 286 297 * used with the assignment operator to make it exception … … 360 371 */ 361 372 void add_subquery(const Query::Internal * subq); 362 373 374 void set_dbl_parameter(double dbl_parameter_) { 375 dbl_parameter = dbl_parameter_; 376 } 377 363 378 /** Finish off the construction. 364 379 */ 365 380 Query::Internal * end_construction(); -
xapian-core/api/omqueryinternal.cc
3 3 * Copyright 1999,2000,2001 BrightStation PLC 4 4 * Copyright 2002 Ananova Ltd 5 5 * Copyright 2002,2003,2004,2005,2006,2007 Olly Betts 6 * Copyright 2006 Lemur Consulting Ltd6 * Copyright 2006,2007 Lemur Consulting Ltd 7 7 * 8 8 * This program is free software; you can redistribute it and/or 9 9 * modify it under the terms of the GNU General Public License as … … 28 28 #include "omqueryinternal.h" 29 29 #include "utils.h" 30 30 #include "serialise.h" 31 #include "serialise-double.h" 31 32 32 33 #include <xapian/error.h> 33 34 #include <xapian/enquire.h> … … 40 41 #include <algorithm> 41 42 #include <math.h> 42 43 #include <limits.h> 44 #include <cfloat> 43 45 44 46 using namespace std; 45 47 … … 58 60 case Xapian::Query::OP_ELITE_SET: 59 61 case Xapian::Query::OP_VALUE_RANGE: 60 62 return 0; 63 case Xapian::Query::OP_MULT_WEIGHT: 64 return 1; 61 65 case Xapian::Query::OP_FILTER: 62 66 case Xapian::Query::OP_AND_MAYBE: 63 67 case Xapian::Query::OP_AND_NOT: … … 75 79 case Xapian::Query::Internal::OP_LEAF: 76 80 case Xapian::Query::OP_VALUE_RANGE: 77 81 return 0; 82 case Xapian::Query::OP_MULT_WEIGHT: 83 return 1; 78 84 case Xapian::Query::OP_FILTER: 79 85 case Xapian::Query::OP_AND_MAYBE: 80 86 case Xapian::Query::OP_AND_NOT: … … 177 183 result += str_parameter; 178 184 result += om_tostring(parameter); 179 185 break; 186 case Xapian::Query::OP_MULT_WEIGHT: 187 result += "."; 188 result += serialise_double(dbl_parameter); 189 break; 180 190 } 181 191 } 182 192 return result; … … 202 212 case Xapian::Query::OP_PHRASE: name = "PHRASE"; break; 203 213 case Xapian::Query::OP_ELITE_SET: name = "ELITE_SET"; break; 204 214 case Xapian::Query::OP_VALUE_RANGE: name = "VALUE_RANGE"; break; 215 case Xapian::Query::OP_MULT_WEIGHT: name = "MULT_WEIGHT"; break; 205 216 } 206 217 return name; 207 218 } … … 248 259 if (!description.empty()) description += opstr; 249 260 description += (**i).get_description(); 250 261 } 262 263 if (op == Xapian::Query::OP_MULT_WEIGHT) { 264 description += " * "; 265 description += om_tostring(dbl_parameter); 266 } 267 251 268 return "(" + description + ")"; 252 269 } 253 270 … … 451 468 return new Xapian::Query::Internal(Xapian::Query::OP_VALUE_RANGE, valno, 452 469 start, stop); 453 470 } 471 case '.': { 472 AutoPtr<Xapian::Query::Internal> result( 473 qint_from_vector(Xapian::Query::OP_MULT_WEIGHT, subqs)); 474 result->set_dbl_parameter(unserialise_double(&p, end)); 475 return result.release(); 476 } 454 477 default: 455 478 DEBUGLINE(UNKNOWN, "Can't parse remainder `" << p - 1 << "'"); 456 479 throw Xapian::InvalidArgumentError("Invalid query string"); … … 498 521 std::swap(str_parameter, other.str_parameter); 499 522 std::swap(term_pos, other.term_pos); 500 523 std::swap(wqf, other.wqf); 524 std::swap(dbl_parameter, other.dbl_parameter); 501 525 } 502 526 503 527 Xapian::Query::Internal::Internal(const Xapian::Query::Internal ©me) … … 508 532 tname(copyme.tname), 509 533 str_parameter(copyme.str_parameter), 510 534 term_pos(copyme.term_pos), 511 wqf(copyme.wqf) 535 wqf(copyme.wqf), 536 dbl_parameter(copyme.dbl_parameter) 512 537 { 513 538 for (subquery_list::const_iterator i = copyme.subqs.begin(); 514 539 i != copyme.subqs.end(); … … 672 697 // match anything. 673 698 if (tname > str_parameter) return 0; 674 699 return this; 700 case OP_MULT_WEIGHT: 701 if (fabs(dbl_parameter - 1.0) > DBL_EPSILON) return this; 702 // If the multiplier is 1, this node doesn't actually do anything, 703 // so we leave it to be removed. 704 break; 675 705 case OP_PHRASE: case OP_NEAR: 676 706 // Default to the number of subqueries. 677 707 if (!parameter) parameter = subqs.size(); -
xapian-core/api/omquery.cc
3 3 * Copyright 1999,2000,2001 BrightStation PLC 4 4 * Copyright 2001,2002 Ananova Ltd 5 5 * Copyright 2003,2004,2005,2006,2007 Olly Betts 6 * Copyright 2006 Lemur Consulting Ltd6 * Copyright 2006,2007 Lemur Consulting Ltd 7 7 * 8 8 * This program is free software; you can redistribute it and/or 9 9 * modify it under the terms of the GNU General Public License as … … 132 132 } 133 133 } 134 134 135 Query::Query(Query::op op_, Xapian::Query q, double parameter) 136 { 137 DEBUGAPICALL(void, "Xapian::Query::Query", 138 op_ << ", " << q << ", " << parameter); 139 try { 140 start_construction(op_, 0); 141 internal->set_dbl_parameter(parameter); 142 add_subquery(q); 143 end_construction(); 144 } catch (...) { 145 abort_construction(); 146 throw; 147 } 148 } 149 135 150 Query::Query(Query::op op_, Xapian::valueno valno, 136 151 const string &begin, const string &end) 137 152 : internal(new Query::Internal(op_, valno, begin, end)) -
xapian-bindings/python/pythontest.py
817 817 del dbr 818 818 shutil.rmtree(dbpath) 819 819 820 def test_mult_weight(): 821 """Test query OP_MULT_WEIGHT feature. 822 823 """ 824 db = setup_database() 825 for mult in (-2.5, -1, 0, 1, 2.5): 826 context("checking queries with OP_MULT_WEIGHT with a multipler of %r" % 827 mult) 828 query1 = xapian.Query("it") 829 query2 = xapian.Query(xapian.Query.OP_MULT_WEIGHT, query1, mult) 830 831 enquire = xapian.Enquire(db) 832 enquire.set_query(query1) 833 mset1 = enquire.get_mset(0, 10) 834 enquire.set_query(query2) 835 mset2 = enquire.get_mset(0, 10) 836 if mult <= 0: 837 expected = [(0, item.docid) for item in mset1] 838 expected.sort() 839 else: 840 expected = [(item.weight * mult, item.docid) for item in mset1] 841 expect([(item.weight, item.docid) for item in mset2], expected) 842 843 844 def test_weight_normalise(): 845 """Test normalising of query weights using the OP_MULT_WEIGHT feature. 846 847 This test first runs a search (asking for no results) to get the maximum 848 possible weight for a query, and then checks that the results of 849 MSet.get_max_possible() match this. 850 851 This tests that the get_max_possible() value is correct (though it isn't 852 guaranteed to be at a tight bound), and that the mult-weight query can 853 compensate correctly. 854 855 """ 856 db = setup_database() 857 for query in ( 858 "it", 859 "was", 860 "it was", 861 "it was four", 862 "it was four five", 863 "\"was it warm\" four notpresent", 864 "notpresent", 865 ): 866 context("checking query %r using OP_MULT_WEIGHT to normalise the weights" % query) 867 qp = xapian.QueryParser() 868 query1 = qp.parse_query(query) 869 enquire = xapian.Enquire(db) 870 enquire.set_query(query1) 871 mset1 = enquire.get_mset(0, 0) 872 873 # Check the max_attained value is 0 - this gives us some reassurance 874 # that the match didn't actually do the work of calculating any 875 # results. 876 expect(mset1.get_max_attained(), 0) 877 878 max_possible = mset1.get_max_possible() 879 mult = 1.0 / max_possible 880 query2 = xapian.Query(xapian.Query.OP_MULT_WEIGHT, query1, mult) 881 882 enquire = xapian.Enquire(db) 883 enquire.set_query(query2) 884 mset2 = enquire.get_mset(0, 10) 885 # max_possible should be 1 (excluding rounding errors) for mset2 886 expect(int(mset2.get_max_possible() * 1000000.0 + 0.5), 1000000) 887 for item in mset2: 888 expect(item.weight > 0, True) 889 expect(item.weight <= 1, True) 890 891 820 892 # The legacy sequence API is only supported for Python >= 2.3 so don't try 821 893 # testing it for Python 2.2. 822 894 vinfo = sys.version_info -
xapian-bindings/xapian.i
7 7 * Copyright 2001,2002 Ananova Ltd 8 8 * Copyright 2002,2003,2005 James Aylett 9 9 * Copyright 2002,2003,2004,2005,2006,2007 Olly Betts 10 * Copyright 2007 Lemur Consulting Ltd 10 11 * 11 12 * This program is free software; you can redistribute it and/or 12 13 * modify it under the terms of the GNU General Public License as … … 839 840 OP_NEAR, 840 841 OP_PHRASE, 841 842 OP_VALUE_RANGE, 842 OP_ELITE_SET = 10 843 OP_ELITE_SET = 10, 844 OP_MULT_WEIGHT 843 845 }; 844 846 // FIXME wrap optional arguments in PHP? 845 847 Query(const string &tname, termcount wqf = 1, termpos term_pos = 0); … … 868 870 /** Apply the specified operator to a single Xapian::Query object. */ 869 871 Query(Query::op op_, Xapian::Query q); 870 872 873 /** Apply the specified operator to a single Xapian::Query object, with a parameter. */ 874 Query(Query::op op_, Xapian::Query q, double parameter); 875 871 876 /** Constructs a new empty query object */ 872 877 Query(); 873 878