xapian-core  1.4.18
query.h
Go to the documentation of this file.
1 
4 /* Copyright (C) 2011,2012,2013,2014,2015,2016,2017,2018,2019 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 
47  public:
49  class Internal;
52 
66 
75  static const Xapian::Query MatchAll;
76 
78  enum op {
84  OP_AND = 0,
85 
92  OP_OR = 1,
93 
99  OP_AND_NOT = 2,
100 
107  OP_XOR = 3,
108 
118  OP_AND_MAYBE = 4,
119 
128  OP_FILTER = 5,
129 
140  OP_NEAR = 6,
141 
152  OP_PHRASE = 7,
153 
158  OP_VALUE_RANGE = 8,
159 
166  OP_SCALE_WEIGHT = 9,
167 
206  OP_ELITE_SET = 10,
207 
214  OP_VALUE_GE = 11,
215 
222  OP_VALUE_LE = 12,
223 
230  OP_SYNONYM = 13,
231 
240  OP_MAX = 14,
241 
246  OP_WILDCARD = 15,
247 
254  OP_INVALID = 99,
255 
257  LEAF_TERM = 100,
258 
261 
268 
273  LEAF_MATCH_NOTHING
274  };
275 
276  enum {
298  WILDCARD_LIMIT_MOST_FREQUENT
299  };
300 
310  XAPIAN_NOTHROW(Query()) { }
311 
313  ~Query() { }
314 
319  Query(const Query & o) : internal(o.internal) { }
320 
325  Query & operator=(const Query & o) { internal = o.internal; return *this; }
326 
327 #ifdef XAPIAN_MOVE_SEMANTICS
328  Query(Query &&) = default;
330 
332  Query & operator=(Query &&) = default;
333 #endif
334 
344  Query(const std::string & term,
345  Xapian::termcount wqf = 1,
346  Xapian::termpos pos = 0);
347 
349  explicit Query(Xapian::PostingSource * source);
350 
356  Query(double factor, const Xapian::Query & subquery);
357 
367  Query(op op_, const Xapian::Query & subquery, double factor);
368 
375  Query(op op_, const Xapian::Query & a, const Xapian::Query & b)
376  {
377  init(op_, 2);
378  bool positional = (op_ == OP_NEAR || op_ == OP_PHRASE);
379  add_subquery(positional, a);
380  add_subquery(positional, b);
381  done();
382  }
383 
390  Query(op op_, const std::string & a, const std::string & b)
391  {
392  init(op_, 2);
393  add_subquery(false, a);
394  add_subquery(false, b);
395  done();
396  }
397 
404  Query(op op_, Xapian::valueno slot, const std::string & range_limit);
405 
413  Query(op op_, Xapian::valueno slot,
414  const std::string & range_lower, const std::string & range_upper);
415 
436  Query(op op_,
437  const std::string & pattern,
438  Xapian::termcount max_expansion = 0,
439  int max_type = WILDCARD_LIMIT_ERROR,
440  op combiner = OP_SYNONYM);
441 
457  template<typename I>
458  Query(op op_, I begin, I end, Xapian::termcount window = 0)
459  {
460  if (begin != end) {
461  typedef typename std::iterator_traits<I>::iterator_category iterator_category;
462  init(op_, window, begin, end, iterator_category());
463  bool positional = (op_ == OP_NEAR || op_ == OP_PHRASE);
464  for (I i = begin; i != end; ++i) {
465  add_subquery(positional, *i);
466  }
467  done();
468  }
469  }
470 
471 #ifdef SWIG
472  // SWIG's %template doesn't seem to handle a templated ctor so we
473  // provide this fake specialised form of the above prototype.
474  Query(op op_, XapianSWIGQueryItor qbegin, XapianSWIGQueryItor qend,
475  Xapian::termcount parameter = 0);
476 
477 # ifdef SWIGJAVA
478  Query(op op_, XapianSWIGStrItor qbegin, XapianSWIGStrItor qend,
479  Xapian::termcount parameter = 0);
480 # endif
481 #endif
482 
490  const TermIterator get_terms_begin() const;
491 
493  const TermIterator XAPIAN_NOTHROW(get_terms_end() const) {
494  return TermIterator();
495  }
496 
504  const TermIterator get_unique_terms_begin() const;
505 
507  const TermIterator XAPIAN_NOTHROW(get_unique_terms_end() const) {
508  return TermIterator();
509  }
510 
512  Xapian::termcount XAPIAN_NOTHROW(get_length() const) XAPIAN_PURE_FUNCTION;
513 
515  bool XAPIAN_NOTHROW(empty() const) {
516  return internal.get() == 0;
517  }
518 
520  std::string serialise() const;
521 
529  static const Query unserialise(const std::string & serialised,
530  const Registry & reg = Registry());
531 
533  op XAPIAN_NOTHROW(get_type() const) XAPIAN_PURE_FUNCTION;
534 
536  size_t XAPIAN_NOTHROW(get_num_subqueries() const) XAPIAN_PURE_FUNCTION;
537 
543  const Query get_subquery(size_t n) const;
544 
546  std::string get_description() const;
547 
555  const Query operator&=(const Query & o);
556 
564  const Query operator|=(const Query & o);
565 
573  const Query operator^=(const Query & o);
574 
579  const Query operator*=(double factor) {
580  return (*this = Query(factor, *this));
581  }
582 
587  const Query operator/=(double factor) {
588  return (*this = Query(1.0 / factor, *this));
589  }
590 
592  explicit Query(Internal * internal_) : internal(internal_) { }
593 
598  explicit Query(Query::op op_) {
599  init(op_, 0);
600  if (op_ != Query::OP_INVALID) done();
601  }
602 
603  private:
604  void init(Query::op op_, size_t n_subqueries, Xapian::termcount window = 0);
605 
606  template<typename I>
607  void init(Query::op op_, Xapian::termcount window,
608  const I & begin, const I & end, std::random_access_iterator_tag)
609  {
610  init(op_, end - begin, window);
611  }
612 
613  template<typename I>
614  void init(Query::op op_, Xapian::termcount window,
615  const I &, const I &, std::input_iterator_tag)
616  {
617  init(op_, 0, window);
618  }
619 
620  void add_subquery(bool positional, const Xapian::Query & subquery);
621 
622  void add_subquery(bool, const std::string & subquery) {
623  add_subquery(false, Xapian::Query(subquery));
624  }
625 
626  void add_subquery(bool positional, const Xapian::Query * subquery) {
627  // FIXME: subquery NULL?
628  add_subquery(positional, *subquery);
629  }
630 
631  void done();
632 };
633 
635 inline const Query
636 operator&(const Query & a, const Query & b)
637 {
638  return Query(Query::OP_AND, a, b);
639 }
640 
642 inline const Query
643 operator|(const Query & a, const Query & b)
644 {
645  return Query(Query::OP_OR, a, b);
646 }
647 
649 inline const Query
650 operator^(const Query & a, const Query & b)
651 {
652  return Query(Query::OP_XOR, a, b);
653 }
654 
660 inline const Query
661 operator*(double factor, const Query & q)
662 {
663  return Query(factor, q);
664 }
665 
671 inline const Query
672 operator*(const Query & q, double factor)
673 {
674  return Query(factor, q);
675 }
676 
682 inline const Query
683 operator/(const Query & q, double factor)
684 {
685  return Query(1.0 / factor, q);
686 }
687 
690  const Query & query;
691 
692  void operator=(const InvertedQuery_ &);
693 
694  explicit InvertedQuery_(const Query & query_) : query(query_) { }
695 
696  public:
697  // GCC 4.2 seems to needs a copy ctor.
698  InvertedQuery_(const InvertedQuery_ & o) : query(o.query) { }
699 
700  operator Query() const {
701  return Query(Query::OP_AND_NOT, Query(std::string()), query);
702  }
703 
704  friend const InvertedQuery_ operator~(const Query &q);
705 
706  friend const Query operator&(const Query & a, const InvertedQuery_ & b);
707 
708  friend const Query operator&=(Query & a, const InvertedQuery_ & b);
709 };
710 
715 inline const Query
716 operator&(const Query & a, const InvertedQuery_ & b)
717 {
718  return Query(Query::OP_AND_NOT, a, b.query);
719 }
720 
725 inline const Query
727 {
728  return (a = Query(Query::OP_AND_NOT, a, b.query));
729 }
730 
731 #ifndef DOXYGEN /* @internal doesn't seem to avoid a warning here. */
732 
733 inline const InvertedQuery_
734 operator~(const Query &q)
735 {
736  return InvertedQuery_(q);
737 }
738 #endif
739 
740 namespace Internal {
741 class AndContext;
742 class OrContext;
743 class XorContext;
744 }
745 
748  public:
749  XAPIAN_NOTHROW(Internal()) { }
750 
751  virtual ~Internal();
752 
753  virtual PostingIterator::Internal * postlist(QueryOptimiser * qopt, double factor) const = 0;
754 
755  virtual void postlist_sub_and_like(Xapian::Internal::AndContext& ctx,
756  QueryOptimiser * qopt,
757  double factor) const;
758 
759  virtual void postlist_sub_or_like(Xapian::Internal::OrContext& ctx,
760  QueryOptimiser * qopt,
761  double factor) const;
762 
763  virtual void postlist_sub_xor(Xapian::Internal::XorContext& ctx,
764  QueryOptimiser * qopt,
765  double factor) const;
766 
767  virtual termcount XAPIAN_NOTHROW(get_length() const) XAPIAN_PURE_FUNCTION;
768 
769  virtual void serialise(std::string & result) const = 0;
770 
771  static Query::Internal * unserialise(const char ** p, const char * end, const Registry & reg);
772 
773  virtual Query::op XAPIAN_NOTHROW(get_type() const) XAPIAN_PURE_FUNCTION = 0;
774  virtual size_t XAPIAN_NOTHROW(get_num_subqueries() const) XAPIAN_PURE_FUNCTION;
775  virtual const Query get_subquery(size_t n) const;
776 
777  virtual std::string get_description() const = 0;
778 
779  // Pass argument as void* to avoid need to include <vector>.
780  virtual void gather_terms(void * void_terms) const;
781 };
782 
783 inline const Query
784 Query::operator&=(const Query & o)
785 {
786  if (o.empty()) {
787  // q &= empty_query sets q to empty_query.
788  *this = o;
789  } else if (this != &o &&
790  internal.get() &&
791  internal->_refs == 1 &&
792  get_type() == OP_AND) {
793  // Appending a subquery to an existing AND.
794  add_subquery(false, o);
795  } else {
796  *this = Query(OP_AND, *this, o);
797  }
798  return *this;
799 }
800 
801 inline const Query
803 {
804  if (o.empty()) {
805  // q |= empty_query is a no-op.
806  } else if (this != &o &&
807  internal.get() &&
808  internal->_refs == 1 &&
809  get_type() == OP_OR) {
810  // Appending a subquery to an existing OR.
811  add_subquery(false, o);
812  } else {
813  *this = Query(OP_OR, *this, o);
814  }
815  return *this;
816 }
817 
818 inline const Query
820 {
821  if (o.empty()) {
822  // q ^= empty_query is a no-op.
823  } else if (internal.get() == o.internal.get()) {
824  // q ^= q gives MatchNothing.
825  internal = NULL;
826  } else if (internal.get() &&
827  internal->_refs == 1 &&
828  get_type() == OP_XOR) {
829  // Appending a subquery to an existing XOR.
830  add_subquery(false, o);
831  } else {
832  *this = Query(OP_XOR, *this, o);
833  }
834  return *this;
835 }
836 
837 }
838 
839 #endif // XAPIAN_INCLUDED_QUERY_H
const TermIterator get_unique_terms_end() const
End iterator for unique terms in the query object.
Definition: query.h:507
The Xapian namespace contains public interfaces for the Xapian library.
Definition: compactor.cc:80
const Query & query
Definition: query.h:690
Query(const Query &o)
Copying is allowed.
Definition: query.h:319
Query & operator=(const Query &o)
Copying is allowed.
Definition: query.h:325
Abstract base class for postlists.
Definition: postlist.h:37
typedefs for Xapian
#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
static const Xapian::Query MatchAll
A query matching all documents.
Definition: query.h:75
Match documents which an odd number of subqueries match.
Definition: query.h:107
op
Query operators.
Definition: query.h:78
void init(Query::op op_, Xapian::termcount window, const I &, const I &, std::input_iterator_tag)
Definition: query.h:614
Compiler attribute macros.
void add_subquery(bool, const std::string &subquery)
Definition: query.h:622
Query(op op_, I begin, I end, Xapian::termcount window=0)
Construct a Query object from a begin/end iterator pair.
Definition: query.h:458
Xapian::Internal::intrusive_ptr< Internal > internal
Definition: query.h:49
const Query operator^=(const Query &o)
Combine with another Xapian::Query object using OP_XOR.
Definition: query.h:819
Query(Query::op op_)
Construct with just an operator.
Definition: query.h:598
#define XAPIAN_VISIBILITY_DEFAULT
Definition: visibility.h:28
const Query operator &=(const Query &o)
Combine with another Xapian::Query object using OP_AND.
Class for iterating over a list of terms.
Definition: termiterator.h:41
const Query operator|(const Query &a, const Query &b)
Combine two Xapian::Query objects using OP_OR.
Definition: query.h:643
unsigned XAPIAN_TERMCOUNT_BASE_TYPE termcount
A counts of terms.
Definition: types.h:72
Value returned by get_type() for MatchAll or equivalent.
Definition: query.h:267
Value returned by get_type() for a PostingSource.
Definition: query.h:260
Define XAPIAN_VISIBILITY_* macros.
Registry for user subclasses.
Definition: registry.h:47
Query()
Construct a query matching no documents.
Definition: query.h:310
const Query operator/(const Query &q, double factor)
Inverse-scale a Xapian::Query object using OP_SCALE_WEIGHT.
Definition: query.h:683
Query(op op_, const Xapian::Query &a, const Xapian::Query &b)
Construct a Query object by combining two others.
Definition: query.h:375
Throw an error if OP_WILDCARD exceeds its expansion limit.
Definition: query.h:282
const Query operator/=(double factor)
Inverse scale using OP_SCALE_WEIGHT.
Definition: query.h:587
Construct an invalid query.
Definition: query.h:254
Base class which provides an "external" source of postings.
Definition: postingsource.h:47
~Query()
Destructor.
Definition: query.h:313
void add_subquery(bool positional, const Xapian::Query *subquery)
Definition: query.h:626
Base class for objects managed by intrusive_ptr.
Definition: intrusive_ptr.h:49
const Query operator &(const Query &a, const Query &b)
Combine two Xapian::Query objects using OP_AND.
Definition: query.h:636
const Query operator|=(const Query &o)
Combine with another Xapian::Query object using OP_OR.
Definition: query.h:802
Match only documents which all subqueries match.
Definition: query.h:84
InvertedQuery_(const Query &query_)
Definition: query.h:694
void init(Query::op op_, Xapian::termcount window, const I &begin, const I &end, std::random_access_iterator_tag)
Definition: query.h:607
const Query operator*(double factor, const Query &q)
Scale a Xapian::Query object using OP_SCALE_WEIGHT.
Definition: query.h:661
const Query operator*=(double factor)
Scale using OP_SCALE_WEIGHT.
Definition: query.h:579
Query(op op_, const std::string &a, const std::string &b)
Construct a Query object by combining two terms.
Definition: query.h:390
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:726
InvertedQuery_(const InvertedQuery_ &o)
Definition: query.h:698
bool empty() const
Check if this query is Xapian::Query::MatchNothing.
Definition: query.h:515
Match documents which the first subquery matches but no others do.
Definition: query.h:99
Match documents which at least one subquery matches.
Definition: query.h:92
unsigned valueno
The number for a value slot in a document.
Definition: types.h:108
unsigned XAPIAN_TERMPOS_BASE_TYPE termpos
A term position within a document or query.
Definition: types.h:83
static const Xapian::Query MatchNothing
A query matching no documents.
Definition: query.h:65
Stop expanding when OP_WILDCARD reaches its expansion limit.
Definition: query.h:288
Class for iterating over a list of document ids.
const Query operator^(const Query &a, const Query &b)
Combine two Xapian::Query objects using OP_XOR.
Definition: query.h:650
Class representing a query.
Definition: query.h:46
A smart pointer that uses intrusive reference counting.
Definition: intrusive_ptr.h:81
const TermIterator get_terms_end() const
End iterator for terms in the query object.
Definition: query.h:493
Class for iterating over a list of terms.
Query(Internal *internal_)
Definition: query.h:592
Class for looking up user subclasses during unserialisation.