summaryrefslogtreecommitdiff
path: root/src/mongo/db/matcher
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/matcher')
-rw-r--r--src/mongo/db/matcher/expression_parser_text.cpp13
-rw-r--r--src/mongo/db/matcher/expression_parser_text_test.cpp46
-rw-r--r--src/mongo/db/matcher/expression_text.cpp16
-rw-r--r--src/mongo/db/matcher/expression_text.h9
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