Elasticsearch throwing an error during startup - spring-boot

I have implemented Elasticsearch in spring boot. On every server restart, I am getting the following error.
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'productController': Unsatisfied dependency expressed through field 'ps'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'productServiceImpl': Unsatisfied dependency expressed through field 'pr'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'productRepository': Invocation of init method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.elasticsearch.repository.support.SimpleElasticsearchRepository]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Rejecting mapping update to [products] as the final mapping would have more than 1 type: [_doc, product]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:639) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
I have deleted the index every time to start the server and then perform the index. Can anyone suggest to me what will the solution

Elasticsearch v6 and above cannot have more than one type per index. But from your exception, your mapping is trying to create more than one type on an index (_doc and product)
Refer https://www.elastic.co/guide/en/elasticsearch/reference/6.0/removal-of-types.html for more info.

As mentioned #Karthick from Elasticsearch 6.X more than one type per index is deprecated and only _doc internal and default mapping type is supported till version 7(for backward compatibility purpose) and that too will be completely removed from soon to be released 8.X major version.
You need to remove your own type name product to solve the issue.
As mentioned in the official link why it's removed.
In an Elasticsearch index, fields that have the same name in different
mapping types are backed by the same Lucene field internally. In other
words, using the example above, the user_name field in the user type
is stored in exactly the same field as the user_name field in the
tweet type, and both user_name fields must have the same mapping
(definition) in both types.
This can lead to frustration when, for example, you want deleted to be
a date field in one type and a boolean field in another type in the
same index.
On top of that, storing different entities that have few or no fields
in common in the same index leads to sparse data and interferes with
Lucene’s ability to compress documents efficiently.
For these reasons, we have decided to remove the concept of mapping
types from Elasticsearch.

Related

Distinct Column Selection using Spring JPA Specifications and Pagination gives InvalidDataAccessApiUsageException

I am trying to filter results from a table based on a bunch of query parameters I receive using Spring Data JPA Specifications. I need to get results of Distinct Column which is of type UUID. All the other query params I need to query by are of type String.
So the repository method I try is findDistinctByTransactionId(Specficiation<T> spec, Pageable page)
I expect the result to be of type Page<UUID>. But I get an exception. The error message is :
org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [org.springframework.data.jpa.domain.Specifications#7c900524] did not match expected type [java.util.UUID (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [org.springframework.data.jpa.domain.Specifications#7c900524] did not match expected type [java.util.UUID (n/a)]
So the problem here is the way to let the JPA know that the Distinct Column we are looking for is of type UUID.
The problem is that you are trying to combine two distinct feature of Spring Data JPA: Specifications and Query Derivation. This does not work.
What you should do is create a custom method implementation of your method which constructs a query using the JPA Criteria API and then adds the predicate you pass in as an argument.

Elasticsearch how nested object connection to parent document

I want to understand what cost to fetch a parent document with nested document in it.
Internally, nested objects index each object in the array as a separate hidden document, meaning that each nested object can be queried independently of the others...
I can't find the explanation how nested document relate to it parent in ES document. Do parent document hold nested ojbect _id, when we fetch parent, it just find source of nested object via id and replace that object to id in the result?
Overall idea of nested objects is the following - instead of relying on ids for join as parent-child approach is doing it utilise the logical organisation of the documents
Each nested object is written just before the parent document:
NESTED_DOC11 NESTED_DOC12 PARENT_DOC1 NESTED_DOC21 NESTED_DOC22 PARENT_DOC2
this is a smart trick which is utilised all the time to do efficient querying on the nested object without doing heavy lookups by ids.
However, this implies some limitations - for example you couldn't update/delete/add nested document without reindexing the whole "block"
More information on this approach is there

Spring Redis Data gives UncategorizedKeyValueException: nested exception is java.lang.NullPointerException

I'm using redis as my secondary db in my spring application and i need to get all records that have null values for certain attributes. I create query in repository to achieve that.
method
findAllByCars(Integer c);
it works when using with integer as the param but when i use it to find all records that Cars is null.
repo.findAllByCars(null)
it's gives below error in stack trace.
rg.springframework.data.keyvalue.core.UncategorizedKeyValueException: nested exception is java.lang.NullPointerException
at org.springframework.data.keyvalue.core.KeyValuePersistenceExceptionTranslator.translateExceptionIfPossible(KeyValuePersistenceExceptionTranslator.java:49)
at org.springframework.data.keyvalue.core.KeyValueTemplate.resolveExceptionIfPossible(KeyValueTemplate.java:484)
at org.springframework.data.keyvalue.core.KeyValueTemplate.execute(KeyValueTemplate.java:379)
at org.springframework.data.keyvalue.core.KeyValueTemplate.find(KeyValueTemplate.java:390)
Anyone can help this with?.

Removing objects from nested fields in ElasticSearch

Is there a way in ElasticSearch wherein I can remove some the objects in the nested field array.
So I have a nested field and it returns array of objects. I need to remove some objects in the nested field.
Is it possible to do so in the query or I need to do that in my code
These extra nested documents are hidden; we can’t access them directly. To update, add, or remove a nested object, we have to reindex the whole document. It’s important to note that, the result returned by a search request is not the nested object alone; it is the whole document.
Nested Objects Elastic search
As far as I know, In Elasticsearch you can't just remove part of a existing document. You should change the document (remove objects you don't need) and renew(rewrite) the document.

Why Elasticsearch have conflicting field mappings on migration from 1.x to 2.x?

I want to upgrade my elastic from 1.5.2 to 2.1.1 and when I use the migration plugin to find problems to solve, before the migration itself, I get errors on "Conflicting field mappings".
In the documentation about this issue, it says that:
Fields with the same name, in the same index, in different types, must have the same mapping, with the exception of the copy_to, dynamic, enabled, ignore_above, include_in_all, and properties parameters, which may have different settings per field. [...] Elasticsearch will not start in the presence of conflicting field mappings. These indices must be deleted or reindexed using a new mapping.
I failed to understand the reason it is the way it is... I mean why "Fields with the same name, in the same index, in different types, must have the same mapping"?
The problem is that types are stored in the same Lucene index. Lucene does not work with the context of type. Therefore the name of the field when used in two different types is the same as stored in Lucene. As Lucene uses the same name they have to have the same type.
So the following two fields will be added to the same field in Lucene:
index - type - field
myindex - type_a - fieldOne
myindex - type_b - fieldOne
In the lucene index are all called: fieldOne

Resources