createIndex=true doesn't create the index mapping in Elasticsearch - spring

createIndex=true doesn't create the index mapping in Elasticsearch using spring-data-elasticsearch
#Document(indexName = "profiles", shards=1, versionType = VersionType.INTERNAL, createIndex = true)

Setting the parameter createIndex = true (which by the way is the default value) by itself does not do anything.
You need to have a Spring Data Elasticsearch repository with the entity class that has this annotation in your application, and the index must not yet exist.
The check if the index exists is done on repository bootstrapping and only if the index does not exist, it will be created and the mappings are written to the index.

Related

Documents with new field added before mapping update not queryable via new field

I have an index that for one reason or another we've added fields to that don't exist in our mapping. For example:
{
"name": "Bob" // Exists in mapping
"age": 12 // doesn't existing in mapping
}
After updating the mapping to add the age field, any document we add the age field to is queryable, but none of the documents that had age added before we updated the mapping are queryable.
Is there a way to tell Elastic to make those older documents queryable, not just any net-new/updated after the mapping update?
This implies that you must have dynamic: false in your mapping, i.e. whenever you send a new field, you prevent ES from creating it automatically.
Once you have updated your mapping, you can then simply call _update_by_query on your index in order to update it and have it reindex the data it contains with the new mappings.
Your queries will then work also on the "older" data.

How to create a composite index programmatically in spring Mongo data in Spring or spring boot?

How to create a MongoDB composite index with Spring Data programmatically in Java?
Using MongoTemplate I can create an index like that:
mongoTemplate.indexOps("collectionName").ensureIndex(new Index().on("fieldName", Sort.Direction.DESC).
Is there a way to create a composite key?
I saw that there is the class CompoundIndexDefinition that, by its name seems to be doing that, but I could not get it to work.
You can create compound indexes on any collection using Spring Data programmatically in Java as below:
// Compound indexes on the fields: fieldOne & fieldTwo
// db.groups.createIndex({fieldOne:1, fieldTwo:1})
IndexDefinition index =
new CompoundIndexDefinition(new Document().append("fieldOne", 1).append("fieldTwo", 1));
mongoTemplate.indexOps(CollectionName.class).ensureIndex(index);
The above example will create same index as on mongo shell:
db.groups.createIndex({fieldOne:1, fieldTwo:1})
With Spring Data, you can create index programmatically using MongoTemplate or MongoOperations
mongoTemplate.indexOps(CollectionName.class)
.ensureIndex(new Index().on("fieldOne", Sort.Direction.DESC)
.on("fieldTwo", Sort.Direction.ASC));
mongoOperations.indexOps(CollectionName.class)
.ensureIndex(new Index().on("fieldOne", Sort.Direction.DESC)
.on("fieldTwo", Sort.Direction.ASC));
I think this is the more appropriate approach.
#CompoundIndexes({
#CompoundIndex(name = "customIndex", def = "{'fieldOne' : 1, 'fieldTwo': 1}")
})
public class Entity {}
In spring boot JPA Mongo repository.

spring-data-mongodb using the fieldName instead of _id

I have a Pojo with an attribute as
Class A{
#Id
#Field("item_id")
private String itemId;
}
When i try to update a document in MongoDB collection based on the itemId as below, it worked well and able to see from mongo ops logs that the query was transformed as "_id in itemIds "
Query query = new Query(Criteria.where("itemId").in(itemIds));
Update update = new Update();
update.set("field2", "abd");
mongoTemplate.updateMulti(query, update, A.class)
When i upgraded to spring-data-mongodb-2.1.5.RELEASE, the query i saw in the mongo logs was "item_id in itemIds". Since item_id is not a field and no index for that field in the collection, the query took forever to complete.
Any help to understand why the spring-data library is building the query as _id in older version and using the field as it is in newer version?
After a 2 minute search on the Spring documentation (https://docs.spring.io/spring-data/mongodb/docs/1.3.3.RELEASE/reference/html/mapping-chapter.html):
The following outlines what field will be mapped to the '_id' document field:
A field annotated with #Id (org.springframework.data.annotation.Id) will be mapped to the '_id' field.
A field without an annotation but named id will be mapped to the '_id' field.
Did you try that already?

How to set OpType on IndexQuery in Spring Data Elasticsearch

Assume spring-boot-starter-data-elasticsearch version 2.1.0.RC1.
Take the following, simple implementation for indexing an entity:
IndexQuery indexQuery = new IndexQueryBuilder().withId(entity.getId()).withObject(entity).build();
String id = elasticsearchTemplate.index(indexQuery);
How do I set the OpType.CREATE on this operation, so that I can assure only documents get indexed which don't already exist?
The equivalent REST API request would look like the following:
POST /{index}/{entity id}?op_type=create
{
"id" : "{entity id}",
"attribute" : "value"
}
This is not supported at the moment by Spring Data ES.
There's a open issue that reports exactly that feature, you might want to check it out: https://jira.spring.io/browse/DATAES-247

Spring Elastic Search Custom Field names

I am new to Elastic Search and I am trying to implement it using Spring-data-elasticsearch.
I have fields with names such as "Transportation", "Telephone_Number" in our elastic search documents.
When I try to map my #Domain object fields with those, I don't get any data for those as I couldn't successfully map those fields.
Tried to use #Field, was disappointed as it didn't have 'name' property in it to map with custom field name.
Tried different variations of a GETTER function, none of those seem to be mapping to those fields.
I started wondering if there's something I'm missing here.
How does a domain object field look like which should map to a filed called something like "Transportation" ?
Any help appreciated
You can use custom name. Spring Data ES use Jackson. So, you can use #JsonProperty("your_custom_name") to enable custom name in ES Mapping
for example:
#Document(indexName = "your_index_name", type = "your_type_name")
public class YourEntity {
....
#JsonProperty("my_transportation")
#Field(type = FieldType.String, searchAnalyzer = "standard", indexAnalyzer = "standard", store = true) // just for example
private String myTransportation;
....
}
Note: I'm sorry anyway, my english is bad.. :D

Resources