mirror of
https://github.com/typesense/typesense.git
synced 2025-05-22 23:06:30 +08:00
add support for include exclude fields in doc fetch (#1782)
Co-authored-by: Kishore Nallan <kishorenc@gmail.com>
This commit is contained in:
parent
e1615dddf8
commit
2f16a71d98
@ -1498,6 +1498,12 @@ bool patch_update_documents(const std::shared_ptr<http_req>& req, const std::sha
|
||||
bool get_fetch_document(const std::shared_ptr<http_req>& req, const std::shared_ptr<http_res>& res) {
|
||||
std::string doc_id = req->params["id"];
|
||||
|
||||
const char* INCLUDE_FIELDS = "include_fields";
|
||||
const char* EXCLUDE_FIELDS = "exclude_fields";
|
||||
|
||||
spp::sparse_hash_set<std::string> exclude_fields;
|
||||
spp::sparse_hash_set<std::string> include_fields;
|
||||
|
||||
CollectionManager & collectionManager = CollectionManager::get_instance();
|
||||
auto collection = collectionManager.get_collection(req->params["collection"]);
|
||||
if(collection == nullptr) {
|
||||
@ -1512,7 +1518,34 @@ bool get_fetch_document(const std::shared_ptr<http_req>& req, const std::shared_
|
||||
return false;
|
||||
}
|
||||
|
||||
res->set_200(doc_option.get().dump(-1, ' ', false, nlohmann::detail::error_handler_t::ignore));
|
||||
if(req->params.count(INCLUDE_FIELDS) != 0) {
|
||||
std::vector<std::string> include_fields_vec;
|
||||
StringUtils::split(req->params[INCLUDE_FIELDS], include_fields_vec, ",");
|
||||
include_fields = spp::sparse_hash_set<std::string>(include_fields_vec.begin(), include_fields_vec.end());
|
||||
}
|
||||
|
||||
if(req->params.count(EXCLUDE_FIELDS) != 0) {
|
||||
std::vector<std::string> exclude_fields_vec;
|
||||
StringUtils::split(req->params[EXCLUDE_FIELDS], exclude_fields_vec, ",");
|
||||
exclude_fields = spp::sparse_hash_set<std::string>(exclude_fields_vec.begin(), exclude_fields_vec.end());
|
||||
}
|
||||
|
||||
nlohmann::json doc = doc_option.get();
|
||||
|
||||
for(auto it = doc.begin(); it != doc.end(); ++it) {
|
||||
if(!include_fields.empty() && include_fields.count(it.key()) == 0) {
|
||||
doc.erase(it.key());
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!exclude_fields.empty() && exclude_fields.count(it.key()) != 0) {
|
||||
doc.erase(it.key());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
res->set_200(doc.dump(-1, ' ', false, nlohmann::detail::error_handler_t::ignore));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2071,4 +2071,85 @@ TEST_F(CoreAPIUtilsTest, CollectionUpdateValidation) {
|
||||
req->body = alter_schema.dump();
|
||||
ASSERT_FALSE(patch_update_collection(req, res));
|
||||
ASSERT_EQ("{\"message\": \"Alter payload is empty.\"}", res->body);
|
||||
}
|
||||
|
||||
TEST_F(CoreAPIUtilsTest, DocumentGetIncludeExcludeFields) {
|
||||
std::vector<field> fields = {
|
||||
field("title", field_types::STRING, false),
|
||||
field("brand", field_types::STRING, true, true),
|
||||
field("size", field_types::INT32, true, false),
|
||||
field("colors", field_types::STRING_ARRAY, true, false),
|
||||
field("rating", field_types::FLOAT, true, false)
|
||||
};
|
||||
|
||||
auto coll1 = collectionManager.get_collection("coll1").get();
|
||||
if(coll1 == nullptr) {
|
||||
coll1 = collectionManager.create_collection("coll1", 4, fields, "rating").get();
|
||||
}
|
||||
|
||||
nlohmann::json doc;
|
||||
doc["id"] = "1";
|
||||
doc["title"] = "Denim jeans";
|
||||
doc["brand"] = "Spykar";
|
||||
doc["size"] = 40;
|
||||
doc["colors"] = {"blue", "black", "grey"};
|
||||
doc["rating"] = 4.5;
|
||||
coll1->add(doc.dump());
|
||||
|
||||
doc["id"] = "2";
|
||||
doc["title"] = "Denim jeans";
|
||||
doc["brand"] = "Levis";
|
||||
doc["size"] = 42;
|
||||
doc["colors"] = {"blue", "black"};
|
||||
doc["rating"] = 4.4;
|
||||
coll1->add(doc.dump());
|
||||
|
||||
std::shared_ptr<http_req> req = std::make_shared<http_req>();
|
||||
std::shared_ptr<http_res> res = std::make_shared<http_res>(nullptr);
|
||||
|
||||
req->params["collection"] = "coll1";
|
||||
req->params["id"] = "1";
|
||||
|
||||
//normal doc fetch
|
||||
ASSERT_TRUE(get_fetch_document(req, res));
|
||||
auto resp = nlohmann::json::parse(res->body);
|
||||
ASSERT_EQ(6, resp.size());
|
||||
ASSERT_TRUE(resp.contains("brand"));
|
||||
ASSERT_TRUE(resp.contains("size"));
|
||||
ASSERT_TRUE(resp.contains("colors"));
|
||||
ASSERT_TRUE(resp.contains("rating"));
|
||||
ASSERT_TRUE(resp.contains("id"));
|
||||
ASSERT_TRUE(resp.contains("title"));
|
||||
|
||||
//include fields
|
||||
req->params["include_fields"] = "brand,size,colors";
|
||||
|
||||
ASSERT_TRUE(get_fetch_document(req, res));
|
||||
resp = nlohmann::json::parse(res->body);
|
||||
ASSERT_EQ(3, resp.size());
|
||||
ASSERT_TRUE(resp.contains("brand"));
|
||||
ASSERT_TRUE(resp.contains("size"));
|
||||
ASSERT_TRUE(resp.contains("colors"));
|
||||
ASSERT_FALSE(resp.contains("rating"));
|
||||
|
||||
//exclude fields
|
||||
req->params.erase("include_fields");
|
||||
req->params["exclude_fields"] = "brand,size,colors";
|
||||
ASSERT_TRUE(get_fetch_document(req, res));
|
||||
resp = nlohmann::json::parse(res->body);
|
||||
ASSERT_EQ(3, resp.size());
|
||||
ASSERT_TRUE(resp.contains("id"));
|
||||
ASSERT_TRUE(resp.contains("title"));
|
||||
ASSERT_TRUE(resp.contains("rating"));
|
||||
ASSERT_FALSE(resp.contains("brand"));
|
||||
|
||||
//both include and exclude fields
|
||||
req->params["include_fields"] = "title,rating";
|
||||
req->params["exclude_fields"] = "brand,size,colors";
|
||||
ASSERT_TRUE(get_fetch_document(req, res));
|
||||
resp = nlohmann::json::parse(res->body);
|
||||
ASSERT_EQ(2, resp.size());
|
||||
ASSERT_TRUE(resp.contains("title"));
|
||||
ASSERT_TRUE(resp.contains("rating"));
|
||||
ASSERT_FALSE(resp.contains("id"));
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user