xapian-core  1.4.25
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 
215  OP_ELITE_SET = 10,
216 
223  OP_VALUE_GE = 11,
224 
231  OP_VALUE_LE = 12,
232 
239  OP_SYNONYM = 13,
240 
249  OP_MAX = 14,
250 
255  OP_WILDCARD = 15,
256 
263  OP_INVALID = 99,
264 
266  LEAF_TERM = 100,
267 
270 
277 
282  LEAF_MATCH_NOTHING
283  };
284 
285  enum {
307  WILDCARD_LIMIT_MOST_FREQUENT
308  };
309 
319  XAPIAN_NOTHROW(Query()) { }
320 
322  ~Query() { }
323 
328  Query(const Query & o) : internal(o.internal) { }
329 
334  Query & operator=(const Query & o) { internal = o.internal; return *this; }
335 
336 #ifdef XAPIAN_MOVE_SEMANTICS
337  Query(Query &&) = default;
339 
341  Query & operator=(Query &&) = default;
342 #endif
343 
353  Query(const std::string & term,
354  Xapian::termcount wqf = 1,
355  Xapian::termpos pos = 0);
356 
358  explicit Query(Xapian::PostingSource * source);
359 
365  Query(double factor, const Xapian::Query & subquery);
366 
376  Query(op op_, const Xapian::Query & subquery, double factor);
377 
384  Query(op op_, const Xapian::Query & a, const Xapian::Query & b)
385  {
386  init(op_, 2);
387  bool positional = (op_ == OP_NEAR || op_ == OP_PHRASE);
388  add_subquery(positional, a);
389  add_subquery(positional, b);
390  done();
391  }
392 
399  Query(op op_, const std::string & a, const std::string & b)
400  {
401  init(op_, 2);
402  add_subquery(false, a);
403  add_subquery(false, b);
404  done();
405  }
406 
413  Query(op op_, Xapian::valueno slot, const std::string & range_limit);
414 
422  Query(op op_, Xapian::valueno slot,
423  const std::string & range_lower, const std::string & range_upper);
424 
445  Query(op op_,
446  const std::string & pattern,
447  Xapian::termcount max_expansion = 0,
448  int max_type = WILDCARD_LIMIT_ERROR,
449  op combiner = OP_SYNONYM);
450 
466  template<typename I>
467  Query(op op_, I begin, I end, Xapian::termcount window = 0)
468  {
469  if (begin != end) {
470  typedef typename std::iterator_traits<I>::iterator_category iterator_category;
471  init(op_, window, begin, end, iterator_category());
472  bool positional = (op_ == OP_NEAR || op_ == OP_PHRASE);
473  for (I i = begin; i != end; ++i) {
474  add_subquery(positional, *i);
475  }
476  done();
477  }
478  }
479 
480 #ifdef SWIG
481  // SWIG's %template doesn't seem to handle a templated ctor so we
482  // provide this fake specialised form of the above prototype.
483  Query(op op_, XapianSWIGQueryItor qbegin, XapianSWIGQueryItor qend,
484  Xapian::termcount parameter = 0);
485 
486 # ifdef SWIGJAVA
487  Query(op op_, XapianSWIGStrItor qbegin, XapianSWIGStrItor qend,
488  Xapian::termcount parameter = 0);
489 # endif
490 #endif
491 
499  const TermIterator get_terms_begin() const;
500 
502  const TermIterator XAPIAN_NOTHROW(get_terms_end() const) {
503  return TermIterator();
504  }
505 
513  const TermIterator get_unique_terms_begin() const;
514 
516  const TermIterator XAPIAN_NOTHROW(get_unique_terms_end() const) {
517  return TermIterator();
518  }
519 
521  Xapian::termcount XAPIAN_NOTHROW(get_length() const) XAPIAN_PURE_FUNCTION;
522 
524  bool XAPIAN_NOTHROW(empty() const) {
525  return internal.get() == 0;
526  }
527 
529  std::string serialise() const;
530 
538  static const Query unserialise(const std::string & serialised,
539  const Registry & reg = Registry());
540 
542  op XAPIAN_NOTHROW(get_type() const) XAPIAN_PURE_FUNCTION;
543 
545  size_t XAPIAN_NOTHROW(get_num_subqueries() const) XAPIAN_PURE_FUNCTION;
546 
552  const Query get_subquery(size_t n) const;
553 
555  std::string get_description() const;
556 
564  const Query operator&=(const Query & o);
565 
573  const Query operator|=(const Query & o);
574 
582  const Query operator^=(const Query & o);
583 
588  const Query operator*=(double factor) {
589  return (*this = Query(factor, *this));
590  }
591 
596  const Query operator/=(double factor) {
597  return (*this = Query(1.0 / factor, *this));
598  }
599 
601  explicit Query(Internal * internal_) : internal(internal_) { }
602 
607  explicit Query(Query::op op_) {
608  init(op_, 0);
609  if (op_ != Query::OP_INVALID) done();
610  }
611 
612  private:
613  void init(Query::op op_, size_t n_subqueries, Xapian::termcount window = 0);
614 
615  template<typename I>
616  void init(Query::op op_, Xapian::termcount window,
617  const I & begin, const I & end, std::random_access_iterator_tag)
618  {
619  init(op_, end - begin, window);
620  }
621 
622  template<typename I>
623  void init(Query::op op_, Xapian::termcount window,
624  const I &, const I &, std::input_iterator_tag)
625  {
626  init(op_, 0, window);
627  }
628 
629  void add_subquery(bool positional, const Xapian::Query & subquery);
630 
631  void add_subquery(bool, const std::string & subquery) {
632  add_subquery(false, Xapian::Query(subquery));
633  }
634 
635  void add_subquery(bool positional, const Xapian::Query * subquery) {
636  // FIXME: subquery NULL?
637  add_subquery(positional, *subquery);
638  }
639 
640  void done();
641 };
642 
644 inline const Query
645 operator&(const Query & a, const Query & b)
646 {
647  return Query(Query::OP_AND, a, b);
648 }
649 
651 inline const Query
652 operator|(const Query & a, const Query & b)
653 {
654  return Query(Query::OP_OR, a, b);
655 }
656 
658 inline const Query
659 operator^(const Query & a, const Query & b)
660 {
661  return Query(Query::OP_XOR, a, b);
662 }
663 
669 inline const Query
670 operator*(double factor, const Query & q)
671 {
672  return Query(factor, q);
673 }
674 
680 inline const Query
681 operator*(const Query & q, double factor)
682 {
683  return Query(factor, q);
684 }
685 
691 inline const Query
692 operator/(const Query & q, double factor)
693 {
694  return Query(1.0 / factor, q);
695 }
696 
699  const Query & query;
700 
701  void operator=(const InvertedQuery_ &);
702 
703  explicit InvertedQuery_(const Query & query_) : query(query_) { }
704 
705  public:
706  // GCC 4.2 seems to needs a copy ctor.
707  InvertedQuery_(const InvertedQuery_ & o) : query(o.query) { }
708 
709  operator Query() const {
710  return Query(Query::OP_AND_NOT, Query(std::string()), query);
711  }
712 
713  friend const InvertedQuery_ operator~(const Query &q);
714 
715  friend const Query operator&(const Query & a, const InvertedQuery_ & b);
716 
717  friend const Query operator&=(Query & a, const InvertedQuery_ & b);
718 };
719 
724 inline const Query
725 operator&(const Query & a, const InvertedQuery_ & b)
726 {
727  return Query(Query::OP_AND_NOT, a, b.query);
728 }
729 
734 inline const Query
736 {
737  return (a = Query(Query::OP_AND_NOT, a, b.query));
738 }
739 
740 #ifndef DOXYGEN /* @internal doesn't seem to avoid a warning here. */
741 
742 inline const InvertedQuery_
743 operator~(const Query &q)
744 {
745  return InvertedQuery_(q);
746 }
747 #endif
748 
749 namespace Internal {
750 class AndContext;
751 class OrContext;
752 class XorContext;
753 }
754 
757  public:
758  XAPIAN_NOTHROW(Internal()) { }
759 
760  virtual ~Internal();
761 
762  virtual PostingIterator::Internal * postlist(QueryOptimiser * qopt, double factor) const = 0;
763 
764  virtual void postlist_sub_and_like(Xapian::Internal::AndContext& ctx,
765  QueryOptimiser * qopt,
766  double factor) const;
767 
768  virtual void postlist_sub_or_like(Xapian::Internal::OrContext& ctx,
769  QueryOptimiser * qopt,
770  double factor) const;
771 
772  virtual void postlist_sub_xor(Xapian::Internal::XorContext& ctx,
773  QueryOptimiser * qopt,
774  double factor) const;
775 
776  virtual termcount XAPIAN_NOTHROW(get_length() const) XAPIAN_PURE_FUNCTION;
777 
778  virtual void serialise(std::string & result) const = 0;
779 
780  static Query::Internal * unserialise(const char ** p, const char * end, const Registry & reg);
781 
782  virtual Query::op XAPIAN_NOTHROW(get_type() const) XAPIAN_PURE_FUNCTION = 0;
783  virtual size_t XAPIAN_NOTHROW(get_num_subqueries() const) XAPIAN_PURE_FUNCTION;
784  virtual const Query get_subquery(size_t n) const;
785 
786  virtual std::string get_description() const = 0;
787 
788  // Pass argument as void* to avoid need to include <vector>.
789  virtual void gather_terms(void * void_terms) const;
790 };
791 
792 inline const Query
793 Query::operator&=(const Query & o)
794 {
795  if (o.empty()) {
796  // q &= empty_query sets q to empty_query.
797  *this = o;
798  } else if (this != &o &&
799  internal.get() &&
800  internal->_refs == 1 &&
801  get_type() == OP_AND) {
802  // Appending a subquery to an existing AND.
803  add_subquery(false, o);
804  } else {
805  *this = Query(OP_AND, *this, o);
806  }
807  return *this;
808 }
809 
810 inline const Query
812 {
813  if (o.empty()) {
814  // q |= empty_query is a no-op.
815  } else if (this != &o &&
816  internal.get() &&
817  internal->_refs == 1 &&
818  get_type() == OP_OR) {
819  // Appending a subquery to an existing OR.
820  add_subquery(false, o);
821  } else {
822  *this = Query(OP_OR, *this, o);
823  }
824  return *this;
825 }
826 
827 inline const Query
829 {
830  if (o.empty()) {
831  // q ^= empty_query is a no-op.
832  } else if (internal.get() == o.internal.get()) {
833  // q ^= q gives MatchNothing.
834  internal = NULL;
835  } else if (internal.get() &&
836  internal->_refs == 1 &&
837  get_type() == OP_XOR) {
838  // Appending a subquery to an existing XOR.
839  add_subquery(false, o);
840  } else {
841  *this = Query(OP_XOR, *this, o);
842  }
843  return *this;
844 }
845 
846 }
847 
848 #endif // XAPIAN_INCLUDED_QUERY_H
const TermIterator get_unique_terms_end() const
End iterator for unique terms in the query object.
Definition: query.h:516
The Xapian namespace contains public interfaces for the Xapian library.
Definition: compactor.cc:80
const Query & query
Definition: query.h:699
Query(const Query &o)
Copying is allowed.
Definition: query.h:328
Query & operator=(const Query &o)
Copying is allowed.
Definition: query.h:334
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:623
Compiler attribute macros.
void add_subquery(bool, const std::string &subquery)
Definition: query.h:631
Query(op op_, I begin, I end, Xapian::termcount window=0)
Construct a Query object from a begin/end iterator pair.
Definition: query.h:467
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:828
Query(Query::op op_)
Construct with just an operator.
Definition: query.h:607
#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:652
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:276
Value returned by get_type() for a PostingSource.
Definition: query.h:269
Define XAPIAN_VISIBILITY_* macros.
Registry for user subclasses.
Definition: registry.h:47
Query()
Construct a query matching no documents.
Definition: query.h:319
const Query operator/(const Query &q, double factor)
Inverse-scale a Xapian::Query object using OP_SCALE_WEIGHT.
Definition: query.h:692
Query(op op_, const Xapian::Query &a, const Xapian::Query &b)
Construct a Query object by combining two others.
Definition: query.h:384
Throw an error if OP_WILDCARD exceeds its expansion limit.
Definition: query.h:291
const Query operator/=(double factor)
Inverse scale using OP_SCALE_WEIGHT.
Definition: query.h:596
Construct an invalid query.
Definition: query.h:263
Base class which provides an "external" source of postings.
Definition: postingsource.h:47
~Query()
Destructor.
Definition: query.h:322
void add_subquery(bool positional, const Xapian::Query *subquery)
Definition: query.h:635
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:645
const Query operator|=(const Query &o)
Combine with another Xapian::Query object using OP_OR.
Definition: query.h:811
Match only documents which all subqueries match.
Definition: query.h:84
InvertedQuery_(const Query &query_)
Definition: query.h:703
void init(Query::op op_, Xapian::termcount window, const I &begin, const I &end, std::random_access_iterator_tag)
Definition: query.h:616
const Query operator*(double factor, const Query &q)
Scale a Xapian::Query object using OP_SCALE_WEIGHT.
Definition: query.h:670
const Query operator*=(double factor)
Scale using OP_SCALE_WEIGHT.
Definition: query.h:588
Query(op op_, const std::string &a, const std::string &b)
Construct a Query object by combining two terms.
Definition: query.h:399
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:735
InvertedQuery_(const InvertedQuery_ &o)
Definition: query.h:707
bool empty() const
Check if this query is Xapian::Query::MatchNothing.
Definition: query.h:524
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:297
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:659
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:502
Class for iterating over a list of terms.
Query(Internal *internal_)
Definition: query.h:601
Class for looking up user subclasses during unserialisation.