facet parent for array fields (#1756)

* return object itself as parent for array fields

* make variables const reference
This commit is contained in:
Krunal Gandhi 2024-05-28 03:02:53 +00:00 committed by GitHub
parent 055425a2eb
commit 3ab8517a8c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 127 additions and 3 deletions

View File

@ -479,7 +479,8 @@ public:
bool facet_value_to_string(const facet &a_facet, const facet_count_t &facet_count, nlohmann::json &document,
std::string &value) const;
nlohmann::json get_facet_parent(const std::string& facet_field_name, const nlohmann::json& document) const;
nlohmann::json get_facet_parent(const std::string& facet_field_name, const nlohmann::json& document,
const std::string& val, bool is_array) const;
static void populate_result_kvs(Topster *topster, std::vector<std::vector<KV *>> &result_kvs,
const spp::sparse_hash_map<uint64_t, uint32_t>& groups_processed,

View File

@ -3053,7 +3053,7 @@ Option<nlohmann::json> Collection::search(std::string raw_query,
nlohmann::json parent;
if(the_field.nested && should_return_parent) {
parent = get_facet_parent(the_field.name, document);
parent = get_facet_parent(the_field.name, document, value, the_field.is_array());
}
const auto& highlighted_text = highlight.snippets.empty() ? value : highlight.snippets[0];
@ -3806,7 +3806,8 @@ bool Collection::facet_value_to_string(const facet &a_facet, const facet_count_t
return true;
}
nlohmann::json Collection::get_facet_parent(const std::string& facet_field_name, const nlohmann::json& document) const {
nlohmann::json Collection::get_facet_parent(const std::string& facet_field_name, const nlohmann::json& document,
const std::string& val, bool is_array) const {
std::vector<std::string> tokens;
StringUtils::split(facet_field_name, tokens, ".");
std::vector<nlohmann::json> level_docs;
@ -3832,6 +3833,15 @@ nlohmann::json Collection::get_facet_parent(const std::string& facet_field_name,
if(!parent_found) {
doc = level_docs[0]; //return the top most root
if(is_array) {
const auto& field = tokens[tokens.size() - 1];
for(const auto& obj : doc) {
if(obj[field] == val) {
return obj;
}
}
}
}
return doc;
}

View File

@ -2402,6 +2402,62 @@ TEST_F(CollectionFacetingTest, FacetingReturnParentObject) {
ASSERT_EQ("blue", results["facet_counts"][0]["counts"][1]["value"]);
}
TEST_F(CollectionFacetingTest, FacetingReturnParentArrayFields) {
nlohmann::json schema = R"({
"name": "coll1",
"enable_nested_fields": true,
"fields": [
{"name": "tags.id", "type": "string[]", "facet": true }
]
})"_json;
auto op = collectionManager.create_collection(schema);
ASSERT_TRUE(op.ok());
Collection* coll1 = op.get();
nlohmann::json doc1 = R"({
"tags": [
{
"id": "tag-1",
"name": "name for tag-1"
},
{
"id": "tag-2",
"name": "name for tag-2"
}
]
})"_json;
auto add_op = coll1->add(doc1.dump(), CREATE);
ASSERT_TRUE(add_op.ok());
auto search_op = coll1->search("*", {}, "", {"tags.id"},
{}, {2}, 10, 1, FREQUENCY, {true},
1, spp::sparse_hash_set<std::string>(),
spp::sparse_hash_set<std::string>(), 10, "",
30, 4, "",
Index::TYPO_TOKENS_THRESHOLD, "", "", {},
3, "<mark>", "</mark>", {},
UINT32_MAX, true, false, true,
"", false, 6000 * 1000, 4, 7,
fallback, 4, {off}, INT16_MAX, INT16_MAX,
2, 2, false, "",
true, 0, max_score, 100,
0, 0, "exhaustive", 30000,
2, "", {"tags.id"});
if(!search_op.ok()) {
LOG(ERROR) << search_op.error();
FAIL();
}
auto results = search_op.get();
ASSERT_EQ(1, results["facet_counts"].size());
ASSERT_EQ(2, results["facet_counts"][0]["counts"].size());
ASSERT_EQ("{\"id\":\"tag-2\",\"name\":\"name for tag-2\"}", results["facet_counts"][0]["counts"][0]["parent"].dump());
ASSERT_EQ("tag-2", results["facet_counts"][0]["counts"][0]["value"]);
ASSERT_EQ("{\"id\":\"tag-1\",\"name\":\"name for tag-1\"}", results["facet_counts"][0]["counts"][1]["parent"].dump());
ASSERT_EQ("tag-1", results["facet_counts"][0]["counts"][1]["value"]);
}
TEST_F(CollectionFacetingTest, FacetSortByAlpha) {
nlohmann::json schema = R"({

View File

@ -1992,6 +1992,63 @@ TEST_F(CollectionOptimizedFacetingTest, FacetingReturnParentObject) {
ASSERT_EQ("blue", results["facet_counts"][0]["counts"][1]["value"]);
}
TEST_F(CollectionOptimizedFacetingTest, FacetingReturnParentArrayFields) {
nlohmann::json schema = R"({
"name": "coll1",
"enable_nested_fields": true,
"fields": [
{"name": "tags.id", "type": "string[]", "facet": true }
]
})"_json;
auto op = collectionManager.create_collection(schema);
ASSERT_TRUE(op.ok());
Collection* coll1 = op.get();
nlohmann::json doc1 = R"({
"tags": [
{
"id": "tag-1",
"name": "name for tag-1"
},
{
"id": "tag-2",
"name": "name for tag-2"
}
]
})"_json;
auto add_op = coll1->add(doc1.dump(), CREATE);
ASSERT_TRUE(add_op.ok());
auto search_op = coll1->search("*", {}, "", {"tags.id"},
{}, {2}, 10, 1, FREQUENCY, {true},
1, spp::sparse_hash_set<std::string>(),
spp::sparse_hash_set<std::string>(), 10, "",
30, 4, "",
Index::TYPO_TOKENS_THRESHOLD, "", "", {},
3, "<mark>", "</mark>", {},
UINT32_MAX, true, false, true,
"", false, 6000 * 1000, 4, 7,
fallback, 4, {off}, INT16_MAX, INT16_MAX,
2, 2, false, "",
true, 0, max_score, 100,
0, 0, "exhaustive", 30000,
2, "", {"tags.id"});
if(!search_op.ok()) {
LOG(ERROR) << search_op.error();
FAIL();
}
auto results = search_op.get();
ASSERT_EQ(1, results["facet_counts"].size());
ASSERT_EQ(2, results["facet_counts"][0]["counts"].size());
ASSERT_EQ("{\"id\":\"tag-2\",\"name\":\"name for tag-2\"}", results["facet_counts"][0]["counts"][0]["parent"].dump());
ASSERT_EQ("tag-2", results["facet_counts"][0]["counts"][0]["value"]);
ASSERT_EQ("{\"id\":\"tag-1\",\"name\":\"name for tag-1\"}", results["facet_counts"][0]["counts"][1]["parent"].dump());
ASSERT_EQ("tag-1", results["facet_counts"][0]["counts"][1]["value"]);
}
TEST_F(CollectionOptimizedFacetingTest, FacetSortByAlpha) {
nlohmann::json schema = R"({
"name": "coll1",