Reputation: 31
I need to delete all satisfied data with the bool query. Therefore I'm using "_delete_by_request" with term query.
My logic is simple. I have an userId and productId. I need to delete all satisfied data with those matching ids.
When I debug the code and take the Search Request and send the request as curl to the elasticsearch and everything deleted by matching ids but with RestHighLevelClient my query does not delete anything.
This is a weird sitatuion and right now I don't have any answers. Did I do anything wrong?
My requests and responses are like this;
My dependencies are like this;
testcontainers.version : 1.15.1
spring-boot.version : 2.2.5.RELEASE
java.version : 11
elasticsearch.version : 7.10.2
My Integration Class is like this;
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(initializers = CollectedProductRepositoryTest.Initializer.class)
@Slf4j
public class CollectedProductRepositoryTest {
@ClassRule
public static ElasticsearchContainer es = new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch:7.10.2").withExposedPorts(9200);
@Autowired
private CollectedProductRepository collectedProductRepository;
@Autowired
private ObjectMapper objectMapper;
@Autowired
private RestHighLevelClient elasticSearchClient;
@MockBean
private ProductIntegrationApiService productIntegrationApiService;
private static final String COLLECTED_PRODUCT_ALIAS = "collected_product";
public static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues values = TestPropertyValues.of(
"elasticsearch.urls=" + es.getContainerIpAddress(),
"elasticsearch.port=" + es.getMappedPort(9200)
);
values.applyTo(configurableApplicationContext);
}
}
@Before
public void init() {
deleteIndex();
try {
PutIndexTemplateRequest templateRequest = new PutIndexTemplateRequest("collected_product_template");
String templateSource = FileLoader.read("classpath:elasticsearch/template/collectedProduct_index_template.json");
templateRequest.source(templateSource, XContentType.JSON);
Settings settings = Settings.builder()
.put(templateRequest.settings())
.put("refresh_interval", "1s")
.build();
templateRequest.settings(settings);
elasticSearchClient.indices().putTemplate(templateRequest, RequestOptions.DEFAULT);
createIndex(COLLECTED_PRODUCT_ALIAS);
} catch (Exception e) {
throw new RuntimeException("Error occurred while creating index via template", e);
}
}
private void deleteIndex() {
try {
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(COLLECTED_PRODUCT_ALIAS);
elasticSearchClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
} catch (Exception e) {
log.error("Error on deleting 'collectedProduct' index", e);
}
}
private void createIndex(String indexName) throws IOException {
CreateIndexRequest index = new CreateIndexRequest(indexName);
elasticSearchClient.indices().create(index, RequestOptions.DEFAULT);
}
@AfterClass
public static void tearDown() {
es.stop();
}
@Test
public void it_should_delete_by_query() throws InterruptedException {
//given
CollectedProduct collectedProduct1 = CollectedProduct.builder()
.userId(12)
.product(CollectedProduct.Product.builder().productId("product1").build())
.id("collectedProductId1")
.build();
CollectedProduct collectedProduct2 = CollectedProduct.builder()
.userId(23)
.product(CollectedProduct.Product.builder().productId("product2").build())
.id("collectedProductId2")
.build();
CollectedProduct collectedProduct3 = CollectedProduct.builder()
.userId(12)
.product(CollectedProduct.Product.builder().productId("product1").build())
.id("collectedProductId3")
.build();
CollectedProduct collectedProduct4 = CollectedProduct.builder()
.userId(45)
.product(CollectedProduct.Product.builder().productId("product4").build())
.id("collectedProductId4")
.build();
collectedProductRepository.save(collectedProduct1);
collectedProductRepository.save(collectedProduct2);
collectedProductRepository.save(collectedProduct3);
collectedProductRepository.save(collectedProduct4);
//when
collectedProductRepository.deleteByQuery(12, "product1");
//then
Optional<CollectedProduct> result = collectedProductRepository.findById("collectedProductId1");
assertThat(result).isEmpty();
}
}
My Repository class is like this
@Repository
@Slf4j
@RequiredArgsConstructor
public class CollectedProductRepository {
private static final String COLLECTED_PRODUCT = "collected_product";
private static final String DOC_TYPE = "_doc";
private static final String EXCEPTION_STRING_TEMPLATE = "CollectedProduct could not be indexed on ElasticSearch. id: ";
private final RestHighLevelClient restHighLevelClient;
private final CollectedProductJsonMapper collectedProductJsonMapper;
private final ObjectMapper objectMapper;
public void save(CollectedProduct collectedProduct) {
BulkRequest bulkRequest = new BulkRequest();
try {
bulkRequest.add(
new IndexRequest(COLLECTED_PRODUCT)
.id(collectedProduct.getId())
.type(DOC_TYPE)
.source(objectMapper.writeValueAsString(collectedProduct), XContentType.JSON)
);
restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
} catch (Exception e) {
log.error(EXCEPTION_STRING_TEMPLATE + collectedProduct.getId(), e);
}
}
public void deleteByQuery(Integer userId, String productId) {
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
TermQueryBuilder userTermQuery = QueryBuilders.termQuery("userId", userId);
TermQueryBuilder productTermQuery = QueryBuilders.termQuery("product.productId", productId);
boolQueryBuilder.must(userTermQuery).must(productTermQuery);
DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(COLLECTED_PRODUCT)
.setQuery(boolQueryBuilder);
try {
ActionListener<BulkByScrollResponse> actionListener = new ActionListener<>() {
@Override
public void onResponse(BulkByScrollResponse indexResponse) {
log.debug("");
}
@Override
public void onFailure(Exception e) {
log.error("error");
}
};
restHighLevelClient.deleteByQueryAsync(deleteByQueryRequest, RequestOptions.DEFAULT, actionListener);
} catch (Exception e) {
log.error(EXCEPTION_STRING_TEMPLATE, e);
}
}
public void delete(String id) {
DeleteRequest deleteRequest = new DeleteRequest(COLLECTED_PRODUCT, DOC_TYPE, id);
try {
restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
} catch (Exception e) {
log.error(EXCEPTION_STRING_TEMPLATE + id, e);
}
}
public Optional<CollectedProduct> findById(String id) {
try {
GetResponse response = restHighLevelClient.get(new GetRequest(COLLECTED_PRODUCT).id(id), RequestOptions.DEFAULT);
CollectedProduct collectedProduct = collectedProductJsonMapper.map(response.getSourceAsString());
return Optional.of(collectedProduct);
} catch (Exception exception) {
return Optional.empty();
}
}
}
My elasticsearch-template;
{
"index_patterns": [
"collected_product*"
],
"version": 2,
"settings": {
"index": {
"number_of_shards": "3",
"number_of_replicas": "1",
"refresh_interval": "10s",
"max_terms_count": "1000",
"max_result_window": 1000000
},
"analysis": {
"filter": {
"my_ascii_folding": {
"type": "asciifolding",
"preserve_original": true
}
}
}
},
"mappings": {
"_source": {
"enabled": true
},
"properties": {
"id": {
"type": "keyword"
},
"userId": {
"type": "long"
},
"brandId": {
"type": "long"
},
"collectionIds": {
"type": "keyword"
},
"product": {
"properties": {
"productId": {
"type": "keyword"
},
"productName": {
"type": "text",
"index": false
},
"productImage": {
"type": "text",
"index": false
},
"priceList": {
"type": "nested",
"properties": {
"value": {
"type": "double"
},
"symbol": {
"type": "text",
"index": false
},
"currency": {
"type": "text",
"index": false
},
"type": {
"type": "keyword"
}
}
}
}
},
"createdDate": {
"type": "date",
"format": "yyyy-MM-dd'T'HH:mm:ss"
},
"updatedDate": {
"type": "date",
"format": "yyyy-MM-dd'T'HH:mm:ss"
}
}
}
}
Upvotes: 2
Views: 1172
Reputation: 31
I solved it.
I did not indexed my documents with es index template. That's why my query didn't worked as expected.
After I indexed my documents with template everything worked fine.
Upvotes: 1