mirror of
https://github.com/typesense/typesense.git
synced 2025-05-22 23:06:30 +08:00
Remove values from reference_index
and object_array_reference_index
in Index::remove_field
. (#1787)
This commit is contained in:
parent
9caffccfc8
commit
b471620a24
@ -6806,9 +6806,27 @@ void Index::remove_field(uint32_t seq_id, nlohmann::json& document, const std::s
|
||||
}
|
||||
}
|
||||
} else if(search_field.is_int64()) {
|
||||
const std::vector<int64_t>& values = search_field.is_single_integer() ?
|
||||
std::vector<int64_t>{document[field_name].get<int64_t>()} :
|
||||
document[field_name].get<std::vector<int64_t>>();
|
||||
std::vector<int64_t> values;
|
||||
std::vector<std::pair<uint32_t, uint32_t>> object_array_reference_values;
|
||||
|
||||
if (search_field.is_array() && search_field.nested && search_field.is_reference_helper) {
|
||||
for (const auto &pair: document[field_name]) {
|
||||
if (!pair.is_array() || pair.size() != 2 || !pair[0].is_number_unsigned() ||
|
||||
!pair[1].is_number_unsigned()) {
|
||||
LOG(ERROR) << "`" + field_name + "` object array reference helper field has wrong value `"
|
||||
+ pair.dump() + "`.";
|
||||
continue;
|
||||
}
|
||||
|
||||
object_array_reference_values.emplace_back(seq_id, pair[0]);
|
||||
values.emplace_back(pair[1]);
|
||||
}
|
||||
} else {
|
||||
values = search_field.is_single_integer() ?
|
||||
std::vector<int64_t>{document[field_name].get<int64_t>()} :
|
||||
document[field_name].get<std::vector<int64_t>>();
|
||||
}
|
||||
|
||||
for(int64_t value: values) {
|
||||
if (search_field.range_index) {
|
||||
auto trie = range_index.at(field_name);
|
||||
@ -6821,6 +6839,14 @@ void Index::remove_field(uint32_t seq_id, nlohmann::json& document, const std::s
|
||||
if(search_field.facet) {
|
||||
remove_facet_token(search_field, search_index, std::to_string(value), seq_id);
|
||||
}
|
||||
|
||||
if (reference_index.count(field_name) != 0) {
|
||||
reference_index[field_name]->remove(value, seq_id);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto const& pair: object_array_reference_values) {
|
||||
object_array_reference_index[field_name]->erase(pair);
|
||||
}
|
||||
} else if(search_field.num_dim) {
|
||||
if(!is_update) {
|
||||
|
@ -1210,6 +1210,88 @@ TEST_F(CollectionJoinTest, UpdateDocumentHavingReferenceField) {
|
||||
doc = coll->get("4").get();
|
||||
ASSERT_EQ(1, doc.count("product_id_sequence_id"));
|
||||
ASSERT_EQ(1, doc["product_id_sequence_id"]);
|
||||
|
||||
schema_json =
|
||||
R"({
|
||||
"name": "Users",
|
||||
"fields": [
|
||||
{"name": "name", "type": "string"}
|
||||
]
|
||||
})"_json;
|
||||
documents = {
|
||||
R"({
|
||||
"id": "user_a",
|
||||
"name": "Joe"
|
||||
})"_json,
|
||||
R"({
|
||||
"id": "user_b",
|
||||
"name": "Dan"
|
||||
})"_json,
|
||||
};
|
||||
collection_create_op = collectionManager.create_collection(schema_json);
|
||||
ASSERT_TRUE(collection_create_op.ok());
|
||||
for (auto const &json: documents) {
|
||||
auto add_op = collection_create_op.get()->add(json.dump());
|
||||
ASSERT_TRUE(add_op.ok());
|
||||
}
|
||||
|
||||
schema_json =
|
||||
R"({
|
||||
"name": "Repos",
|
||||
"fields": [
|
||||
{"name": "name", "type": "string"},
|
||||
{"name": "stargazers", "type": "string[]", "reference": "Users.id"}
|
||||
]
|
||||
})"_json;
|
||||
documents = {
|
||||
R"({
|
||||
"id": "repo_a",
|
||||
"name": "Typesense",
|
||||
"stargazers": ["user_a", "user_b"]
|
||||
})"_json,
|
||||
};
|
||||
collection_create_op = collectionManager.create_collection(schema_json);
|
||||
ASSERT_TRUE(collection_create_op.ok());
|
||||
for (auto const &json: documents) {
|
||||
auto add_op = collection_create_op.get()->add(json.dump());
|
||||
ASSERT_TRUE(add_op.ok());
|
||||
}
|
||||
|
||||
req_params = {
|
||||
{"collection", "Repos"},
|
||||
{"q", "*"},
|
||||
{"include_fields", "$Users(name)"}
|
||||
};
|
||||
search_op = collectionManager.do_search(req_params, embedded_params, json_res, now_ts);
|
||||
ASSERT_TRUE(search_op.ok());
|
||||
|
||||
res_obj = nlohmann::json::parse(json_res);
|
||||
ASSERT_EQ(1, res_obj["found"].get<size_t>());
|
||||
ASSERT_EQ(1, res_obj["hits"].size());
|
||||
ASSERT_EQ(2, res_obj["hits"][0]["document"]["Users"].size());
|
||||
ASSERT_EQ("Joe", res_obj["hits"][0]["document"]["Users"][0]["name"]);
|
||||
ASSERT_EQ("Dan", res_obj["hits"][0]["document"]["Users"][1]["name"]);
|
||||
|
||||
auto json = R"({
|
||||
"stargazers": ["user_b"]
|
||||
})"_json;
|
||||
|
||||
auto add_op = collection_create_op.get()->add(json.dump(), index_operation_t::UPDATE, "repo_a", DIRTY_VALUES::REJECT);
|
||||
ASSERT_TRUE(add_op.ok());
|
||||
|
||||
req_params = {
|
||||
{"collection", "Repos"},
|
||||
{"q", "*"},
|
||||
{"include_fields", "$Users(name)"}
|
||||
};
|
||||
search_op = collectionManager.do_search(req_params, embedded_params, json_res, now_ts);
|
||||
ASSERT_TRUE(search_op.ok());
|
||||
|
||||
res_obj = nlohmann::json::parse(json_res);
|
||||
ASSERT_EQ(1, res_obj["found"].get<size_t>());
|
||||
ASSERT_EQ(1, res_obj["hits"].size());
|
||||
ASSERT_EQ(1, res_obj["hits"][0]["document"]["Users"].size());
|
||||
ASSERT_EQ("Dan", res_obj["hits"][0]["document"]["Users"][0]["name"]);
|
||||
}
|
||||
|
||||
TEST_F(CollectionJoinTest, FilterByReference_SingleMatch) {
|
||||
@ -4054,7 +4136,6 @@ TEST_F(CollectionJoinTest, FilterByObjectReferenceField) {
|
||||
{"include_fields", "$Portions(*, strategy:merge)"}
|
||||
};
|
||||
search_op_bool = collectionManager.do_search(req_params, embedded_params, json_res, now_ts);
|
||||
LOG(INFO) << search_op_bool.error();
|
||||
ASSERT_TRUE(search_op_bool.ok());
|
||||
|
||||
res_obj = nlohmann::json::parse(json_res);
|
||||
@ -4083,6 +4164,55 @@ TEST_F(CollectionJoinTest, FilterByObjectReferenceField) {
|
||||
ASSERT_EQ(1 , res_obj["hits"][0]["document"]["portions"][2].at("count"));
|
||||
|
||||
|
||||
ASSERT_EQ("Bread", res_obj["hits"][1]["document"]["name"]);
|
||||
ASSERT_EQ(1, res_obj["hits"][1]["document"].count("portions"));
|
||||
ASSERT_EQ(1, res_obj["hits"][1]["document"]["portions"].size());
|
||||
|
||||
ASSERT_EQ(5, res_obj["hits"][1]["document"]["portions"][0].size());
|
||||
ASSERT_EQ("portion_a", res_obj["hits"][1]["document"]["portions"][0].at("portion_id"));
|
||||
ASSERT_EQ(500 , res_obj["hits"][1]["document"]["portions"][0].at("quantity"));
|
||||
ASSERT_EQ("g", res_obj["hits"][1]["document"]["portions"][0].at("unit"));
|
||||
ASSERT_EQ(10 , res_obj["hits"][1]["document"]["portions"][0].at("count"));
|
||||
|
||||
auto doc = R"({
|
||||
"name": "Milk",
|
||||
"portions": [
|
||||
{
|
||||
"portion_id": "portion_c",
|
||||
"count": 1
|
||||
}
|
||||
]
|
||||
})"_json;
|
||||
|
||||
auto add_op = collectionManager.get_collection_unsafe("Foods")->add(doc.dump(), index_operation_t::UPDATE, "1",
|
||||
DIRTY_VALUES::REJECT);
|
||||
ASSERT_TRUE(add_op.ok());
|
||||
|
||||
req_params = {
|
||||
{"collection", "Foods"},
|
||||
{"q", "*"},
|
||||
{"include_fields", "$Portions(*, strategy:merge)"}
|
||||
};
|
||||
search_op_bool = collectionManager.do_search(req_params, embedded_params, json_res, now_ts);
|
||||
ASSERT_TRUE(search_op_bool.ok());
|
||||
|
||||
res_obj = nlohmann::json::parse(json_res);
|
||||
ASSERT_EQ(2, res_obj["found"].get<size_t>());
|
||||
ASSERT_EQ(2, res_obj["hits"].size());
|
||||
ASSERT_EQ(3, res_obj["hits"][0]["document"].size());
|
||||
ASSERT_EQ(1, res_obj["hits"][0]["document"].count("name"));
|
||||
|
||||
ASSERT_EQ("Milk", res_obj["hits"][0]["document"]["name"]);
|
||||
ASSERT_EQ(1, res_obj["hits"][0]["document"].count("portions"));
|
||||
ASSERT_EQ(1, res_obj["hits"][0]["document"]["portions"].size());
|
||||
|
||||
ASSERT_EQ(5, res_obj["hits"][0]["document"]["portions"][0].size());
|
||||
ASSERT_EQ("portion_c", res_obj["hits"][0]["document"]["portions"][0].at("portion_id"));
|
||||
ASSERT_EQ(500 , res_obj["hits"][0]["document"]["portions"][0].at("quantity"));
|
||||
ASSERT_EQ("ml", res_obj["hits"][0]["document"]["portions"][0].at("unit"));
|
||||
ASSERT_EQ(1 , res_obj["hits"][0]["document"]["portions"][0].at("count"));
|
||||
|
||||
|
||||
ASSERT_EQ("Bread", res_obj["hits"][1]["document"]["name"]);
|
||||
ASSERT_EQ(1, res_obj["hits"][1]["document"].count("portions"));
|
||||
ASSERT_EQ(1, res_obj["hits"][1]["document"]["portions"].size());
|
||||
|
Loading…
x
Reference in New Issue
Block a user