spring-data-elasticsearch - #Field mapping type ignored when #Id annotated on the same field - elasticsearch

#Document(indexName = "opportunity_data", type = "opportunities", createIndex = false)
#Setting(settingPath = "/search/settings.json")
#Data
#Accessors(chain = true)
#JsonIgnoreProperties(value = {"id"}, allowGetters = true, allowSetters = false)
public class OpportunityVo extends AbstractGenericVo<Opportunity> {
#Id
#Field(type = FieldType.Long)
private Long opportunityId;
#Field(type = FieldType.Long)
private Long prospectId;
#Field(type = FieldType.Text)
private String prospectName;
}
mapping to keyword snapshot
the opportunityId above is mapped to keyword other than the long type. Anyone knows how to map the opportunityId to long type when #Id annotated at the same time since I'd like to do stats metrics aggregation on this property?

Stats aggregation can be only applied to numerics. Change the mappings works fine. But #Id will be mapped to keyword , still no luck.

Related

How to search float fields as text in elastic using QueryBuilder

I ve document named plan that correspond plan entity
#Entity
#Table(name = "plan")
#Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
#org.springframework.data.elasticsearch.annotations.Document(indexName = "plan")
public class Plan extends AbstractAuditingEntity implements Serializable {
#Id
#GeneratedValue
#Column(name = "id")
#Field(type = FieldType.Text , fielddata = true)
private UUID id;
#NotNull
#Column(name = "name", nullable = false, unique = true)
private String name;
#Column(name = "description")
private String description;
#Column(name = "current_price")
#Field(type = FieldType.Text , fielddata = true )
private Float currentPrice;
}
Here my method search implementation
public Page<Plan> search(String query, Pageable pageable) {
NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(queryStringQuery("*"+query+"*").defaultOperator(Operator.AND));
nativeSearchQuery.setPageable(pageable);
List<Plan> hits = elasticsearchTemplate
.search(nativeSearchQuery, Plan.class)
.map(SearchHit::getContent)
.stream()
.collect(Collectors.toList());
return new PageImpl<>(hits, pageable, hits.size());
}
Name and Description are searchable but float field isn't .
Marking as FieldType.Float doesn't give expected result .

Searching multiple fields with multiple queries in Spring Elasticsearch

I am using Spring Elasticsearch. This is my java class :
#Entity
#Document(indexName = "shopindex")
public class Shop implements Serializable {
private #Id #GeneratedValue(strategy = GenerationType.IDENTITY) Long id;
private String imagePath;
#Field(type = FieldType.Text, name = "name")
private String name;
#Field(type = FieldType.Text, name = "description")
private String description;
#Field(type = FieldType.Text, name = "address")
private String address;
#Field(type = FieldType.Text, name = "locality")
private String locality;
#Field(type = FieldType.Keyword, name = "city")
private String city;
#Field(type = FieldType.Keyword, name = "state")
private String state;
private String timing;
#Field(type = FieldType.Nested, includeInParent = true)
private ArrayList<Listing> listings;
Shop () {}
}
I want to have two query strings, location and query. I want query to search through fields name, description, and listing and location to search through fields address, location, city, and state. I am using this query for search but I am getting exception :
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(boolQuery.must(QueryBuilders.multiMatchQuery(location, "address", "locality", "city", "state"))
.must(boolQuery.should(QueryBuilders.multiMatchQuery(query, "name", "description"))
.should(QueryBuilders
.nestedQuery("listings",
QueryBuilders.multiMatchQuery(query, "listings.name", "listings.description"),ScoreMode.Avg))))
.build();
Iterable<Shop> itr = searchRepository.search(searchQuery);

Error while indexing in Hibernate Search - Could not get property value

I am using Hibernate Search with Spring Boot to create a searchable rest api. Trying to POST an instance of "Training", I receive the following stack traces. None of the two are very insightful to me which is why I am reaching out for help.
Stack trace:
https://pastebin.com/pmurg1N3
It appears to me that it is trying to index a null entity!? How can that happen? Any ideas?
The entity:
#Entity #Getter #Setter #NoArgsConstructor
#ToString(onlyExplicitlyIncluded = true)
#Audited #Indexed(index = "Training")
#AnalyzerDef(name = "ngram",
tokenizer = #TokenizerDef(factory = StandardTokenizerFactory.class ),
filters = {
#TokenFilterDef(factory = StandardFilterFactory.class),
#TokenFilterDef(factory = LowerCaseFilterFactory.class),
#TokenFilterDef(factory = StopFilterFactory.class),
#TokenFilterDef(factory = NGramFilterFactory.class,
params = {
#Parameter(name = "minGramSize", value = "2"),
}
)
}
)
#Analyzer(definition = "ngram")
public class Training implements BaseEntity<Long>, OwnedEntity {
#Id
#GeneratedValue
#ToString.Include
private Long id;
#NotNull
#RestResourceMapper(context = RestResourceContext.IDENTITY, path = "/companies/{id}")
#JsonProperty(access = Access.WRITE_ONLY)
#JsonDeserialize(using = RestResourceURLSerializer.class)
private Long owner;
#NotNull
#Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
private String name;
#Column(length = 10000)
private String goals;
#Column(length = 10000)
private String description;
#Enumerated(EnumType.STRING)
#Field(index = Index.YES, store = Store.YES, analyze = Analyze.NO, bridge=#FieldBridge(impl=EnumBridge.class))
private Audience audience;
#Enumerated(EnumType.STRING)
#Field(index = Index.YES, store = Store.YES, analyze = Analyze.NO, bridge=#FieldBridge(impl=EnumBridge.class))
private Level level;
#ManyToMany
#Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
#NotNull #Size(min = 1)
#IndexedEmbedded
private Set<ProductVersion> versions;
#NotNull
private Boolean enabled = false;
#NotNull
#Min(1)
#IndexedEmbedded
#Field(index = Index.YES, store = Store.YES, analyze = Analyze.NO)
#NumericField
private Integer maxStudents;
#NotNull
#ManyToOne(fetch = FetchType.LAZY)
private Agenda agenda;
#NotNull
#Min(1)
#Field(index = Index.YES, store = Store.YES, analyze = Analyze.NO)
#NumericField
private Integer durationDays;
#IndexedEmbedded
#Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
#ManyToMany(cascade = CascadeType.PERSIST)
private Set<Tag> tags = new HashSet<>();
I'd say either your versions collection or your tags collection contains null objects, which is generally not something we expect in a Hibernate ORM association, and apparently not something Hibernate Search expects either.
Can you check that in debug mode?

Custom query Parameter value [2] did not match expected type

I trying to update a entity with OneToOne relation using restful web service.
I'm using a custom query but it doesnt work
#Modifying
#Query("UPDATE Activity a SET a.type = :type WHERE a.id = :uuid")
int setType(#Param("uuid") UUID uuid, #Param("type") long type);
Error :
java.lang.IllegalArgumentException: Parameter value [2] did not match expected type [com.mezoo.tdc.model.ActivityType (n/a)]
Activity Bean
#Entity
#Table(name= "Activity")
public class Activity implements Serializable{
#Id
#GeneratedValue(generator = "uuid")
#GenericGenerator(name="uuid", strategy = "uuid2")
#Column(name = "uuid", nullable = false, unique = true, columnDefinition = "BINARY(16)")
private UUID uuid;
#OneToOne(fetch = FetchType.EAGER, cascade={CascadeType.MERGE})
#JoinColumn(name="type", nullable = false)
private ActivityType type;
ActivityType Bean
#Entity
#Table(name= "ActivityType")
public class ActivityType implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(nullable = false, unique = true)
private String code;
#Column(nullable = false)
private String label;
It is possible to update without custom queries ?
I would like use POST request like below :
{"uuid":"9d9fa946-ee6e-408e-9e8a-7a9786a1d362","label":"ACTIVITY", "type":{"id":2}}
Update
Activity Repository :
#Transactional
public interface ActivityDao extends CrudRepository<Activity, UUID> {
#Modifying
#Query("UPDATE Activity a SET a.type = :type WHERE a.uuid = :uuid")
int updateType(#Param("uuid") UUID uuid, #Param("type") ActivityType type);
}
Activity Service:
#Service
public class ActivityService implements EntityService<Activity,UUID> {
private static final Logger LOGGER = LoggerFactory.getLogger(ActivityService.class);
#Override
public Activity update(Activity activity) {
LOGGER.info("Update ",activity);
Activity updated = activityDao.findOne(activity.getUuid());
if(updated==null) throw new ResourceNotFoundException();
if (activity.getType().getId()!= updated.getType().getId()) {
LOGGER.info("Update ActivityType for Activity "+activity.getUuid(),activity);
activityDao.updateType(updated.getUuid(),activity.getType());
}
updated.setLabel(activity.getLabel());
updated.setDetails(activity.getDetails());
return activityDao.save(updated);
}
Thanks
your parameter #Param("type") long type is wrong !
it should be #Param("type") ActivityType type.

java.lang.IllegalArgumentException with java persistance API

I am getting a java.lang.IllegalArgumentException similar to the link given below.To solve it I tried to change the field type from Integer to Long. But still I am getting:
Caused by: java.lang.IllegalArgumentException: Parameter value [5] was not matching type [com.buddhiedge.server.entity.StudyplanCategory]
StudyplanCategory is the entity class.
The problem is similar to the one in the below link.
Hibernate - Parameter value [2011] was not matching type [java.lang.Integer]. How to solve?
My entity Class is:
#JsonIgnoreProperties({ "studyplanCategoryList", "dropboxzipfile",
"parentCategory", "createdDate", "updatedDate" })
#JsonPropertyOrder({ "id", "name", "status", "sptTutorialsList" })
#Entity
#Table(name = "studyplan_category", catalog = "buddhiedgeserver_db", schema = "", uniqueConstraints = { #UniqueConstraint(columnNames = { "dropboxzipfile" }) })
#NamedQueries({
#NamedQuery(name = "StudyplanCategory.findSubStudyPlanById", query = "SELECT s FROM StudyplanCategory s WHERE s.parentCategory=:parentCategory order by updatedDate DESC")})
public class StudyplanCategory implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#NotNull
#Column(name = "id", nullable = false)
private Long id;
}
It seems you are passing 5 as parameter to the query. If you want to pass an ID rather than an entity, change the query to:
WHERE s.parentCategory.id=:parentCategoryId

Resources