xapian-core  1.4.31
query.h
Go to the documentation of this file.
1 
4 /* Copyright (C) 2011-2025 Olly Betts
5  * Copyright (C) 2008 Richard Boulton
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #ifndef XAPIAN_INCLUDED_QUERY_H
23 #define XAPIAN_INCLUDED_QUERY_H
24 
25 #if !defined XAPIAN_IN_XAPIAN_H && !defined XAPIAN_LIB_BUILD
26 # error Never use <xapian/query.h> directly; include <xapian.h> instead.
27 #endif
28 
29 #include <string>
30 
31 #include <xapian/attributes.h>
32 #include <xapian/intrusive_ptr.h>
33 #include <xapian/postingiterator.h>
34 #include <xapian/registry.h>
35 #include <xapian/termiterator.h>
36 #include <xapian/types.h>
37 #include <xapian/visibility.h>
38 
39 class QueryOptimiser; // FIXME
40 
41 namespace Xapian {
42 
43 class PostingSource;
44 
45 namespace Internal {
46  // You need a C++11 compiler to build Xapian 1.4.x, but we aim to support
47  // the headers being included without having to select C++11 mode. That's
48  // become much less of an issue as most compilers have switched to at least
49  // C++11 by default, but it seems better not to change this mid release
50  // series, so we define our own version of std::enable_if<>.
51  template<bool, typename T = void> struct EnableIf { };
52  template<typename T> struct EnableIf<true, T> { typedef T type; };
53 }
54 
57  public:
59  class Internal;
62 
76 
85  static const Xapian::Query MatchAll;
86 
88  enum op {
94  OP_AND = 0,
95 
102  OP_OR = 1,
103 
109  OP_AND_NOT = 2,
110 
117  OP_XOR = 3,
118 
128  OP_AND_MAYBE = 4,
129 
138  OP_FILTER = 5,
139 
150  OP_NEAR = 6,
151 
162  OP_PHRASE = 7,
163 
168  OP_VALUE_RANGE = 8,
169 
176  OP_SCALE_WEIGHT = 9,
177 
225  OP_ELITE_SET = 10,
226 
233  OP_VALUE_GE = 11,
234 
241  OP_VALUE_LE = 12,
242 
249  OP_SYNONYM = 13,
250 
259  OP_MAX = 14,
260 
265  OP_WILDCARD = 15,
266 
273  OP_INVALID = 99,
274 
276  LEAF_TERM = 100,
277 
280 
287 
292  LEAF_MATCH_NOTHING
293  };
294 
295  enum {
317  WILDCARD_LIMIT_MOST_FREQUENT
318  };
319 
329  XAPIAN_NOTHROW(Query()) { }
330 
332  ~Query() { }
333 
338  Query(const Query & o) : internal(o.internal) { }
339 
344  Query & operator=(const Query & o) { internal = o.internal; return *this; }
345 
346 #ifdef XAPIAN_MOVE_SEMANTICS
348  Query(Query &&) = default;
349 
351  Query & operator=(Query &&) = default;
352 #endif
353 
363  Query(const std::string & term,
364  Xapian::termcount wqf = 1,
365  Xapian::termpos pos = 0);
366 
368  explicit Query(Xapian::PostingSource * source);
369 
375  Query(double factor, const Xapian::Query & subquery);
376 
386  Query(op op_, const Xapian::Query & subquery, double factor);
387 
394  Query(op op_, const Xapian::Query & a, const Xapian::Query & b)
395  {
396  init(op_, 2);
397  bool positional = (op_ == OP_NEAR || op_ == OP_PHRASE);
398  add_subquery(positional, a);
399  add_subquery(positional, b);
400  done();
401  }
402 
409  Query(op op_, const std::string & a, const std::string & b)
410  {
411  init(op_, 2);
412  add_subquery(false, a);
413  add_subquery(false, b);
414  done();
415  }
416 
423  Query(op op_, Xapian::valueno slot, const std::string & range_limit);
424 
432  Query(op op_, Xapian::valueno slot,
433  const std::string & range_lower, const std::string & range_upper);
434 
455  Query(op op_,
456  const std::string & pattern,
457  Xapian::termcount max_expansion = 0,
458  int max_type = WILDCARD_LIMIT_ERROR,
459  op combiner = OP_SYNONYM);
460 
476  template<typename I,
477  typename T = typename std::iterator_traits<I>,
478  typename V = typename T::value_type,
479  typename Xapian::Internal::EnableIf<sizeof(V) != 1, bool>::type = true,
480  typename iterator_category = typename T::iterator_category>
481  Query(op op_, I begin, I end, Xapian::termcount window = 0)
482  {
483  if (begin != end) {
484  init(op_, window, begin, end, iterator_category());
485  bool positional = (op_ == OP_NEAR || op_ == OP_PHRASE);
486  for (I i = begin; i != end; ++i) {
487  add_subquery(positional, *i);
488  }
489  done();
490  }
491  }
492 
493 #ifdef SWIG
494  // SWIG's %template doesn't seem to handle a templated ctor so we
495  // provide this fake specialised form of the above prototype.
496  Query(op op_, XapianSWIGQueryItor qbegin, XapianSWIGQueryItor qend,
497  Xapian::termcount parameter = 0);
498 
499 # ifdef SWIGJAVA
500  Query(op op_, XapianSWIGStrItor qbegin, XapianSWIGStrItor qend,
501  Xapian::termcount parameter = 0);
502 # endif
503 #endif
504 
512  const TermIterator get_terms_begin() const;
513 
515  const TermIterator XAPIAN_NOTHROW(get_terms_end() const) {
516  return TermIterator();
517  }
518 
526  const TermIterator get_unique_terms_begin() const;
527 
529  const TermIterator XAPIAN_NOTHROW(get_unique_terms_end() const) {
530  return TermIterator();
531  }
532 
534  Xapian::termcount XAPIAN_NOTHROW(get_length() const) XAPIAN_PURE_FUNCTION;
535 
537  bool XAPIAN_NOTHROW(empty() const) {
538  return internal.get() == 0;
539  }
540 
542  std::string serialise() const;
543 
551  static const Query unserialise(const std::string & serialised,
552  const Registry & reg = Registry());
553 
555  op XAPIAN_NOTHROW(get_type() const) XAPIAN_PURE_FUNCTION;
556 
558  size_t XAPIAN_NOTHROW(get_num_subqueries() const) XAPIAN_PURE_FUNCTION;
559 
565  const Query get_subquery(size_t n) const;
566 
568  std::string get_description() const;
569 
577  const Query operator&=(const Query & o);
578 
586  const Query operator|=(const Query & o);
587 
595  const Query operator^=(const Query & o);
596 
601  const Query operator*=(double factor) {
602  return (*this = Query(factor, *this));
603  }
604 
609  const Query operator/=(double factor) {
610  return (*this = Query(1.0 / factor, *this));
611  }
612 
614  explicit Query(Internal * internal_) : internal(internal_) { }
615 
620  explicit Query(Query::op op_) {
621  init(op_, 0);
622  if (op_ != Query::OP_INVALID) done();
623  }
624 
625  private:
626  void init(Query::op op_, size_t n_subqueries, Xapian::termcount window = 0);
627 
628  template<typename I>
629  void init(Query::op op_, Xapian::termcount window,
630  const I & begin, const I & end, std::random_access_iterator_tag)
631  {
632  init(op_, end - begin, window);
633  }
634 
635  template<typename I>
636  void init(Query::op op_, Xapian::termcount window,
637  const I &, const I &, std::input_iterator_tag)
638  {
639  init(op_, 0, window);
640  }
641 
642  void add_subquery(bool positional, const Xapian::Query & subquery);
643 
644  void add_subquery(bool, const std::string & subquery) {
645  add_subquery(false, Xapian::Query(subquery));
646  }
647 
648  void add_subquery(bool positional, const Xapian::Query * subquery) {
649  // FIXME: subquery NULL?
650  add_subquery(positional, *subquery);
651  }
652 
653  void done();
654 };
655 
657 inline const Query
658 operator&(const Query & a, const Query & b)
659 {
660  return Query(Query::OP_AND, a, b);
661 }
662 
664 inline const Query
665 operator|(const Query & a, const Query & b)
666 {
667  return Query(Query::OP_OR, a, b);
668 }
669 
671 inline const Query
672 operator^(const Query & a, const Query & b)
673 {
674  return Query(Query::OP_XOR, a, b);
675 }
676 
682 inline const Query
683 operator*(double factor, const Query & q)
684 {
685  return Query(factor, q);
686 }
687 
693 inline const Query
694 operator*(const Query & q, double factor)
695 {
696  return Query(factor, q);
697 }
698 
704 inline const Query
705 operator/(const Query & q, double factor)
706 {
707  return Query(1.0 / factor, q);
708 }
709 
712  const Query & query;
713 
714  void operator=(const InvertedQuery_ &);
715 
716  explicit InvertedQuery_(const Query & query_) : query(query_) { }
717 
718  public:
719  // GCC 4.2 seems to needs a copy ctor.
721 
722  operator Query() const {
723  return Query(Query::OP_AND_NOT, Query(std::string()), query);
724  }
725 
726  friend const InvertedQuery_ operator~(const Query &q);
727 
728  friend const Query operator&(const Query & a, const InvertedQuery_ & b);
729 
730  friend const Query operator&=(Query & a, const InvertedQuery_ & b);
731 };
732 
737 inline const Query
738 operator&(const Query & a, const InvertedQuery_ & b)
739 {
740  return Query(Query::OP_AND_NOT, a, b.query);
741 }
742 
747 inline const Query
749 {
750  return (a = Query(Query::OP_AND_NOT, a, b.query));
751 }
752 
753 #ifndef DOXYGEN /* @internal doesn't seem to avoid a warning here. */
755 inline const InvertedQuery_
756 operator~(const Query &q)
757 {
758  return InvertedQuery_(q);
759 }
760 #endif
761 
762 namespace Internal {
763 class AndContext;
764 class OrContext;
765 class XorContext;
766 }
767 
770  public:
771  XAPIAN_NOTHROW(Internal()) { }
772 
773  virtual ~Internal();
774 
775  virtual PostingIterator::Internal * postlist(QueryOptimiser * qopt, double factor) const = 0;
776 
777  virtual void postlist_sub_and_like(Xapian::Internal::AndContext& ctx,
778  QueryOptimiser * qopt,
779  double factor) const;
780 
781  virtual void postlist_sub_or_like(Xapian::Internal::OrContext& ctx,
782  QueryOptimiser * qopt,
783  double factor) const;
784 
785  virtual void postlist_sub_xor(Xapian::Internal::XorContext& ctx,
786  QueryOptimiser * qopt,
787  double factor) const;
788 
789  virtual termcount XAPIAN_NOTHROW(get_length() const) XAPIAN_PURE_FUNCTION;
790 
791  virtual void serialise(std::string & result) const = 0;
792 
793  static Query::Internal * unserialise(const char ** p, const char * end, const Registry & reg);
794 
795  virtual Query::op XAPIAN_NOTHROW(get_type() const) XAPIAN_PURE_FUNCTION = 0;
796  virtual size_t XAPIAN_NOTHROW(get_num_subqueries() const) XAPIAN_PURE_FUNCTION;
797  virtual const Query get_subquery(size_t n) const;
798 
799  virtual std::string get_description() const = 0;
800 
801  // Pass argument as void* to avoid need to include <vector>.
802  virtual void gather_terms(void * void_terms) const;
803 };
804 
805 inline const Query
806 Query::operator&=(const Query & o)
807 {
808  if (o.empty()) {
809  // q &= empty_query sets q to empty_query.
810  *this = o;
811  } else if (this != &o &&
812  internal.get() &&
813  internal->_refs == 1 &&
814  get_type() == OP_AND) {
815  // Appending a subquery to an existing AND.
816  add_subquery(false, o);
817  } else {
818  *this = Query(OP_AND, *this, o);
819  }
820  return *this;
821 }
822 
823 inline const Query
825 {
826  if (o.empty()) {
827  // q |= empty_query is a no-op.
828  } else if (this != &o &&
829  internal.get() &&
830  internal->_refs == 1 &&
831  get_type() == OP_OR) {
832  // Appending a subquery to an existing OR.
833  add_subquery(false, o);
834  } else {
835  *this = Query(OP_OR, *this, o);
836  }
837  return *this;
838 }
839 
840 inline const Query
842 {
843  if (o.empty()) {
844  // q ^= empty_query is a no-op.
845  } else if (internal.get() == o.internal.get()) {
846  // q ^= q gives MatchNothing.
847  internal = NULL;
848  } else if (internal.get() &&
849  internal->_refs == 1 &&
850  get_type() == OP_XOR) {
851  // Appending a subquery to an existing XOR.
852  add_subquery(false, o);
853  } else {
854  *this = Query(OP_XOR, *this, o);
855  }
856  return *this;
857 }
858 
859 }
860 
861 #endif // XAPIAN_INCLUDED_QUERY_H
static Xapian::Query query(Xapian::Query::op op, const string &t1=string(), const string &t2=string(), const string &t3=string(), const string &t4=string(), const string &t5=string(), const string &t6=string(), const string &t7=string(), const string &t8=string(), const string &t9=string(), const string &t10=string())
Definition: api_anydb.cc:63
Compiler attribute macros.
#define XAPIAN_PURE_FUNCTION
Like XAPIAN_CONST_FUNCTION, but such a function can also examine global memory, perhaps via pointer o...
Definition: attributes.h:67
Base class for objects managed by intrusive_ptr.
Definition: intrusive_ptr.h:49
A smart pointer that uses intrusive reference counting.
Definition: intrusive_ptr.h:82
friend const InvertedQuery_ operator~(const Query &q)
void operator=(const InvertedQuery_ &)
InvertedQuery_(const InvertedQuery_ &o)
Definition: query.h:720
const Query & query
Definition: query.h:712
InvertedQuery_(const Query &query_)
Definition: query.h:716
Abstract base class for postlists.
Definition: postlist.h:37
Base class which provides an "external" source of postings.
Definition: postingsource.h:48
virtual PostingIterator::Internal * postlist(QueryOptimiser *qopt, double factor) const =0
Class representing a query.
Definition: query.h:56
@ WILDCARD_LIMIT_ERROR
Throw an error if OP_WILDCARD exceeds its expansion limit.
Definition: query.h:301
@ WILDCARD_LIMIT_FIRST
Stop expanding when OP_WILDCARD reaches its expansion limit.
Definition: query.h:307
bool empty() const
Check if this query is Xapian::Query::MatchNothing.
Definition: query.h:537
const Query operator/=(double factor)
Inverse scale using OP_SCALE_WEIGHT.
Definition: query.h:609
const TermIterator get_terms_end() const
End iterator for terms in the query object.
Definition: query.h:515
Query(op op_, const std::string &a, const std::string &b)
Construct a Query object by combining two terms.
Definition: query.h:409
~Query()
Destructor.
Definition: query.h:332
const Query operator^=(const Query &o)
Combine with another Xapian::Query object using OP_XOR.
Definition: query.h:841
const TermIterator get_unique_terms_end() const
End iterator for unique terms in the query object.
Definition: query.h:529
Query(op op_, I begin, I end, Xapian::termcount window=0)
Construct a Query object from a begin/end iterator pair.
Definition: query.h:481
op
Query operators.
Definition: query.h:88
@ LEAF_POSTING_SOURCE
Value returned by get_type() for a PostingSource.
Definition: query.h:279
@ OP_XOR
Match documents which an odd number of subqueries match.
Definition: query.h:117
@ LEAF_MATCH_ALL
Value returned by get_type() for MatchAll or equivalent.
Definition: query.h:286
@ OP_AND
Match only documents which all subqueries match.
Definition: query.h:94
@ OP_OR
Match documents which at least one subquery matches.
Definition: query.h:102
@ OP_AND_NOT
Match documents which the first subquery matches but no others do.
Definition: query.h:109
@ OP_INVALID
Construct an invalid query.
Definition: query.h:273
void add_subquery(bool positional, const Xapian::Query &subquery)
Definition: query.cc:296
Query()
Construct a query matching no documents.
Definition: query.h:329
void init(Query::op op_, Xapian::termcount window, const I &begin, const I &end, std::random_access_iterator_tag)
Definition: query.h:629
void add_subquery(bool, const std::string &subquery)
Definition: query.h:644
static const Xapian::Query MatchNothing
A query matching no documents.
Definition: query.h:75
const Query operator|=(const Query &o)
Combine with another Xapian::Query object using OP_OR.
Definition: query.h:824
Query(Internal *internal_)
Definition: query.h:614
Query(const Query &o)
Copying is allowed.
Definition: query.h:338
void add_subquery(bool positional, const Xapian::Query *subquery)
Definition: query.h:648
Query(op op_, const Xapian::Query &a, const Xapian::Query &b)
Construct a Query object by combining two others.
Definition: query.h:394
Xapian::Internal::intrusive_ptr< Internal > internal
Definition: query.h:59
void init(Query::op op_, Xapian::termcount window, const I &, const I &, std::input_iterator_tag)
Definition: query.h:636
op get_type() const
Get the type of the top level of the query.
Definition: query.cc:212
Query(Query::op op_)
Construct with just an operator.
Definition: query.h:620
Query & operator=(const Query &o)
Copying is allowed.
Definition: query.h:344
static const Xapian::Query MatchAll
A query matching all documents.
Definition: query.h:85
Registry for user subclasses.
Definition: registry.h:47
Class for iterating over a list of terms.
Definition: termiterator.h:41
#define true
Definition: header.h:8
The Xapian namespace contains public interfaces for the Xapian library.
Definition: compactor.cc:80
unsigned XAPIAN_TERMCOUNT_BASE_TYPE termcount
A counts of terms.
Definition: types.h:72
const Query operator^(const Query &a, const Query &b)
Combine two Xapian::Query objects using OP_XOR.
Definition: query.h:672
const Query operator|(const Query &a, const Query &b)
Combine two Xapian::Query objects using OP_OR.
Definition: query.h:665
const Query operator&(const Query &a, const Query &b)
Combine two Xapian::Query objects using OP_AND.
Definition: query.h:658
unsigned valueno
The number for a value slot in a document.
Definition: types.h:108
const Query operator&=(Query &a, const InvertedQuery_ &b)
Combine two Xapian::Query objects using OP_AND_NOT with result in the first.
Definition: query.h:748
const Query operator*(double factor, const Query &q)
Scale a Xapian::Query object using OP_SCALE_WEIGHT.
Definition: query.h:683
unsigned XAPIAN_TERMPOS_BASE_TYPE termpos
A term position within a document or query.
Definition: types.h:83
const Query operator/(const Query &q, double factor)
Inverse-scale a Xapian::Query object using OP_SCALE_WEIGHT.
Definition: query.h:705
Class for iterating over a list of document ids.
Class for looking up user subclasses during unserialisation.
Class for iterating over a list of terms.
typedefs for Xapian
Define XAPIAN_VISIBILITY_* macros.
#define XAPIAN_VISIBILITY_DEFAULT
Definition: visibility.h:28