1 // fts_matcher.h
2 
3 
4 /**
5  *    Copyright (C) 2018-present MongoDB, Inc.
6  *
7  *    This program is free software: you can redistribute it and/or modify
8  *    it under the terms of the Server Side Public License, version 1,
9  *    as published by MongoDB, Inc.
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  *    Server Side Public License for more details.
15  *
16  *    You should have received a copy of the Server Side Public License
17  *    along with this program. If not, see
18  *    <http://www.mongodb.com/licensing/server-side-public-license>.
19  *
20  *    As a special exception, the copyright holders give permission to link the
21  *    code of portions of this program with the OpenSSL library under certain
22  *    conditions as described in each individual source file and distribute
23  *    linked combinations including the program with the OpenSSL library. You
24  *    must comply with the Server Side Public License in all respects for
25  *    all of the code used other than as permitted herein. If you modify file(s)
26  *    with this exception, you may extend this exception to your version of the
27  *    file(s), but you are not obligated to do so. If you do not wish to do so,
28  *    delete this exception statement from your version. If you delete this
29  *    exception statement from all source files in the program, then also delete
30  *    it in the license file.
31  */
32 
33 #pragma once
34 
35 #include "mongo/db/fts/fts_query_impl.h"
36 #include "mongo/db/fts/fts_spec.h"
37 #include "mongo/db/fts/fts_tokenizer.h"
38 #include "mongo/db/fts/tokenizer.h"
39 
40 namespace mongo {
41 
42 namespace fts {
43 
44 class FTSMatcher {
45     MONGO_DISALLOW_COPYING(FTSMatcher);
46 
47 public:
48     FTSMatcher(const FTSQueryImpl& query, const FTSSpec& spec);
49 
50     /**
51      * Returns whether 'obj' matches the query.  An object is considered to match the query
52      * if all four of the following conditions hold:
53      * 1) The object contains at least one positive term.
54      * 2) The object contains zero negative terms.
55      * 3) The object contains all positive phrases.
56      * 4) The object contains zero negative phrases.
57      */
58     bool matches(const BSONObj& obj) const;
59 
60     /**
61      * Returns whether 'obj' contains at least one positive term.
62      */
63     bool hasPositiveTerm(const BSONObj& obj) const;
64 
65     /**
66      * Returns whether 'obj' contains at least one negative term.
67      */
68     bool hasNegativeTerm(const BSONObj& obj) const;
69 
70     /**
71      * Returns whether 'obj' contains all positive phrases.
72      */
73     bool positivePhrasesMatch(const BSONObj& obj) const;
74 
75     /**
76      * Returns whether 'obj' contains zero negative phrases.
77      */
78     bool negativePhrasesMatch(const BSONObj& obj) const;
79 
80 private:
81     /**
82      * For matching, can we skip the positive term check?  This is done as optimization when
83      * we have a-priori knowledge that all documents being matched pass the positive term
84      * check.
85      */
canSkipPositiveTermCheck()86     bool canSkipPositiveTermCheck() const {
87         return !_query.getCaseSensitive() && !_query.getDiacriticSensitive();
88     }
89 
90     /**
91      * Returns whether the string 'raw' contains any positive terms from the query.
92      * 'language' specifies the language for 'raw'.
93      */
94     bool _hasPositiveTerm_string(const FTSLanguage* language, const std::string& raw) const;
95 
96     /**
97      * Returns whether the string 'raw' contains any negative terms from the query.
98      * 'language' specifies the language for 'raw'.
99      */
100     bool _hasNegativeTerm_string(const FTSLanguage* language, const std::string& raw) const;
101 
102     /**
103      * Returns whether 'obj' contains the exact string 'phrase' in any indexed fields.
104      */
105     bool _phraseMatch(const std::string& phrase, const BSONObj& obj) const;
106 
107     /**
108      * Helper method that returns the tokenizer options that this matcher should use, based on the
109      * the query options.
110      */
111     FTSTokenizer::Options _getTokenizerOptions() const;
112 
113     // TODO These should be unowned pointers instead of owned copies.
114     const FTSQueryImpl _query;
115     const FTSSpec _spec;
116 };
117 }
118 }
119