diff options
Diffstat (limited to 'src/mongo/db/matcher')
-rw-r--r-- | src/mongo/db/matcher/expression_parser_text.cpp | 13 | ||||
-rw-r--r-- | src/mongo/db/matcher/expression_parser_text_test.cpp | 46 | ||||
-rw-r--r-- | src/mongo/db/matcher/expression_text.cpp | 16 | ||||
-rw-r--r-- | src/mongo/db/matcher/expression_text.h | 9 |
4 files changed, 78 insertions, 6 deletions
diff --git a/src/mongo/db/matcher/expression_parser_text.cpp b/src/mongo/db/matcher/expression_parser_text.cpp index a01529bee91..6968dc6c0cb 100644 --- a/src/mongo/db/matcher/expression_parser_text.cpp +++ b/src/mongo/db/matcher/expression_parser_text.cpp @@ -79,12 +79,23 @@ StatusWithMatchExpression expressionParserTextCallbackReal(const BSONObj& queryO caseSensitive = caseSensitiveElt.trueValue(); } + BSONElement diacriticSensitiveElt = queryObj["$diacriticSensitive"]; + bool diacriticSensitive = fts::FTSQuery::diacriticSensitiveDefault; + if (!diacriticSensitiveElt.eoo()) { + expectedFieldCount++; + if (mongo::Bool != diacriticSensitiveElt.type()) { + return StatusWithMatchExpression(ErrorCodes::TypeMismatch, + "$diacriticSensitive requires a boolean value"); + } + diacriticSensitive = diacriticSensitiveElt.trueValue(); + } + if (queryObj.nFields() != expectedFieldCount) { return StatusWithMatchExpression(ErrorCodes::BadValue, "extra fields in $text"); } unique_ptr<TextMatchExpression> e(new TextMatchExpression()); - Status s = e->init(query, language, caseSensitive); + Status s = e->init(query, language, caseSensitive, diacriticSensitive); if (!s.isOK()) { return StatusWithMatchExpression(s); } diff --git a/src/mongo/db/matcher/expression_parser_text_test.cpp b/src/mongo/db/matcher/expression_parser_text_test.cpp index 33ab47af773..3d51604f7ef 100644 --- a/src/mongo/db/matcher/expression_parser_text_test.cpp +++ b/src/mongo/db/matcher/expression_parser_text_test.cpp @@ -51,6 +51,7 @@ TEST(MatchExpressionParserText, Basic) { ASSERT_EQUALS(textExp->getQuery(), "awesome"); ASSERT_EQUALS(textExp->getLanguage(), "english"); ASSERT_EQUALS(textExp->getCaseSensitive(), fts::FTSQuery::caseSensitiveDefault); + ASSERT_EQUALS(textExp->getDiacriticSensitive(), fts::FTSQuery::diacriticSensitiveDefault); } TEST(MatchExpressionParserText, LanguageError) { @@ -90,4 +91,49 @@ TEST(MatchExpressionParserText, CaseSensitiveError) { StatusWithMatchExpression result = MatchExpressionParser::parse(query); ASSERT_FALSE(result.isOK()); } + +TEST(MatchExpressionParserText, DiacriticSensitiveTrue) { + BSONObj query = fromjson("{$text: {$search:\"awesome\", $diacriticSensitive: true}}"); + + StatusWithMatchExpression result = MatchExpressionParser::parse(query); + ASSERT_TRUE(result.isOK()); + + ASSERT_EQUALS(MatchExpression::TEXT, result.getValue()->matchType()); + std::unique_ptr<TextMatchExpression> textExp( + static_cast<TextMatchExpression*>(result.getValue().release())); + ASSERT_EQUALS(textExp->getDiacriticSensitive(), true); +} + +TEST(MatchExpressionParserText, DiacriticSensitiveFalse) { + BSONObj query = fromjson("{$text: {$search:\"awesome\", $diacriticSensitive: false}}"); + + StatusWithMatchExpression result = MatchExpressionParser::parse(query); + ASSERT_TRUE(result.isOK()); + + ASSERT_EQUALS(MatchExpression::TEXT, result.getValue()->matchType()); + std::unique_ptr<TextMatchExpression> textExp( + static_cast<TextMatchExpression*>(result.getValue().release())); + ASSERT_EQUALS(textExp->getDiacriticSensitive(), false); +} + +TEST(MatchExpressionParserText, DiacriticSensitiveError) { + BSONObj query = fromjson("{$text:{$search:\"awesome\", $diacriticSensitive: 0}}"); + + StatusWithMatchExpression result = MatchExpressionParser::parse(query); + ASSERT_FALSE(result.isOK()); +} + +TEST(MatchExpressionParserText, DiacriticSensitiveAndCaseSensitiveTrue) { + BSONObj query = + fromjson("{$text: {$search:\"awesome\", $diacriticSensitive: true, $caseSensitive: true}}"); + + StatusWithMatchExpression result = MatchExpressionParser::parse(query); + ASSERT_TRUE(result.isOK()); + + ASSERT_EQUALS(MatchExpression::TEXT, result.getValue()->matchType()); + std::unique_ptr<TextMatchExpression> textExp( + static_cast<TextMatchExpression*>(result.getValue().release())); + ASSERT_EQUALS(textExp->getDiacriticSensitive(), true); + ASSERT_EQUALS(textExp->getCaseSensitive(), true); +} } diff --git a/src/mongo/db/matcher/expression_text.cpp b/src/mongo/db/matcher/expression_text.cpp index 34ea527e6ca..b5ccd9f40bd 100644 --- a/src/mongo/db/matcher/expression_text.cpp +++ b/src/mongo/db/matcher/expression_text.cpp @@ -38,10 +38,14 @@ using std::string; using std::unique_ptr; using stdx::make_unique; -Status TextMatchExpression::init(const string& query, const string& language, bool caseSensitive) { +Status TextMatchExpression::init(const string& query, + const string& language, + bool caseSensitive, + bool diacriticSensitive) { _query = query; _language = language; _caseSensitive = caseSensitive; + _diacriticSensitive = diacriticSensitive; return initPath("_fts"); } @@ -55,7 +59,8 @@ bool TextMatchExpression::matchesSingleElement(const BSONElement& e) const { void TextMatchExpression::debugString(StringBuilder& debug, int level) const { _debugAddSpace(debug, level); debug << "TEXT : query=" << _query << ", language=" << _language - << ", caseSensitive=" << _caseSensitive << ", tag="; + << ", caseSensitive=" << _caseSensitive << ", diacriticSensitive=" << _diacriticSensitive + << ", tag="; MatchExpression::TagData* td = getTag(); if (NULL != td) { td->debugString(&debug); @@ -68,7 +73,7 @@ void TextMatchExpression::debugString(StringBuilder& debug, int level) const { void TextMatchExpression::toBSON(BSONObjBuilder* out) const { out->append("$text", BSON("$search" << _query << "$language" << _language << "$caseSensitive" - << _caseSensitive)); + << _caseSensitive << "$diacriticSensitive" << _diacriticSensitive)); } bool TextMatchExpression::equivalent(const MatchExpression* other) const { @@ -88,12 +93,15 @@ bool TextMatchExpression::equivalent(const MatchExpression* other) const { if (realOther->getCaseSensitive() != _caseSensitive) { return false; } + if (realOther->getDiacriticSensitive() != _diacriticSensitive) { + return false; + } return true; } unique_ptr<MatchExpression> TextMatchExpression::shallowClone() const { unique_ptr<TextMatchExpression> next = make_unique<TextMatchExpression>(); - next->init(_query, _language, _caseSensitive); + next->init(_query, _language, _caseSensitive, _diacriticSensitive); if (getTag()) { next->setTag(getTag()->clone()); } diff --git a/src/mongo/db/matcher/expression_text.h b/src/mongo/db/matcher/expression_text.h index 3dae52c9ed6..371ad037111 100644 --- a/src/mongo/db/matcher/expression_text.h +++ b/src/mongo/db/matcher/expression_text.h @@ -41,7 +41,10 @@ public: TextMatchExpression() : LeafMatchExpression(TEXT) {} virtual ~TextMatchExpression() {} - Status init(const std::string& query, const std::string& language, bool caseSensitive); + Status init(const std::string& query, + const std::string& language, + bool caseSensitive, + bool diacriticSensitive); virtual bool matchesSingleElement(const BSONElement& e) const; @@ -62,11 +65,15 @@ public: bool getCaseSensitive() const { return _caseSensitive; } + bool getDiacriticSensitive() const { + return _diacriticSensitive; + } private: std::string _query; std::string _language; bool _caseSensitive; + bool _diacriticSensitive; }; } // namespace mongo |