Skip to content

Commit

Permalink
facet parent for array fields (#1756)
Browse files Browse the repository at this point in the history
* return object itself as parent for array fields

* make variables const reference
krunal1313 authored May 28, 2024
1 parent 055425a commit 3ab8517
Showing 4 changed files with 127 additions and 3 deletions.
3 changes: 2 additions & 1 deletion include/collection.h
Original file line number Diff line number Diff line change
@@ -479,7 +479,8 @@ class Collection {
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,
14 changes: 12 additions & 2 deletions src/collection.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
56 changes: 56 additions & 0 deletions test/collection_faceting_test.cpp
Original file line number Diff line number Diff line change
@@ -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"({
57 changes: 57 additions & 0 deletions test/collection_optimized_faceting_test.cpp
Original file line number Diff line number Diff line change
@@ -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",

0 comments on commit 3ab8517

Please sign in to comment.