diff --git a/src/filter.cpp b/src/filter.cpp index 6415500d..7d8aa46a 100644 --- a/src/filter.cpp +++ b/src/filter.cpp @@ -607,13 +607,18 @@ Option toFilter(const std::string expression, } else if (_field.is_string()) { size_t filter_value_index = 0; NUM_COMPARATOR str_comparator = CONTAINS; + auto apply_not_equals = false; if (raw_value[0] == '=') { // string filter should be evaluated in strict "equals" mode str_comparator = EQUALS; while (++filter_value_index < raw_value.size() && raw_value[filter_value_index] == ' '); - } else if (raw_value.size() >= 2 && raw_value[0] == '!' && raw_value[1] == '=') { - str_comparator = NOT_EQUALS; - filter_value_index++; + } else if (raw_value.size() >= 2 && raw_value[0] == '!') { + if (raw_value[1] == '=') { + str_comparator = NOT_EQUALS; + filter_value_index++; + } + + apply_not_equals = true; while (++filter_value_index < raw_value.size() && raw_value[filter_value_index] == ' '); } if (filter_value_index == raw_value.size()) { @@ -629,7 +634,7 @@ Option toFilter(const std::string expression, filter_exp = {field_name, {raw_value.substr(filter_value_index)}, {str_comparator}}; } - filter_exp.apply_not_equals = (str_comparator == NOT_EQUALS); + filter_exp.apply_not_equals = apply_not_equals; } else { return Option(400, "Error with filter field `" + _field.name + "`: Unidentified field data type, see docs for supported data types."); diff --git a/test/collection_filtering_test.cpp b/test/collection_filtering_test.cpp index e572c32f..3eaf9336 100644 --- a/test/collection_filtering_test.cpp +++ b/test/collection_filtering_test.cpp @@ -1466,6 +1466,14 @@ TEST_F(CollectionFilteringTest, NegationOperatorBasics) { results = coll1->search("*", {"artist"}, "artist:!=Foobar", {}, {}, {0}, 10, 1, FREQUENCY, {true}, 10).get(); ASSERT_EQ(4, results["found"].get()); + results = coll1->search("*", {"artist"}, "artist:! Jackson", {}, {}, {0}, 10, 1, FREQUENCY, {true}, 10).get(); + ASSERT_EQ(2, results["found"]); + ASSERT_EQ("2", results["hits"][0]["document"]["id"]); + ASSERT_EQ("0", results["hits"][1]["document"]["id"]); + + results = coll1->search("*", {"artist"}, "artist:![Swift, Jackson]", {}, {}, {0}, 10, 1, FREQUENCY, {true}, 10).get(); + ASSERT_EQ(0, results["found"]); + // empty value (bad filtering) auto res_op = coll1->search("*", {"artist"}, "artist:!=", {}, {}, {0}, 10, 1, FREQUENCY, {true}, 10); ASSERT_FALSE(res_op.ok());