Searching for a string from a comma separated field in solr - java

I have installed solr-6.5.1 in my Spring MVC Java Web Application refering the following documentations:
http://www.baeldung.com/apache-solrj
https://github.com/eugenp/tutorials/tree/master/apache-solrj/src/main/java/com/baeldung/solrjava
I have a POJO declared as shown below:
public class WebContentSearchHB
{
private int webContentDefinitionId;
private String pageTitle;
private String pageKwd;
private String pageDesc;
private int siteId;
private int applicationId;
private Date pageCreatedTime;
private Date pageUpdatedDate ;
private String webContentData;
private String webContentType;
private String category;
public int getWebContentDefinitionId()
{
return webContentDefinitionId;
}
#Field("webContentDefinitionId")
public void setWebContentDefinitionId(int webContentDefinitionId)
{
this.webContentDefinitionId = webContentDefinitionId;
}
public String getPageTitle()
{
return pageTitle;
}
#Field("pageTitle")
public void setPageTitle(String pageTitle)
{
this.pageTitle = pageTitle;
}
public String getPageKwd()
{
return pageKwd;
}
#Field("pageKwd")
public void setPageKwd(String pageKwd)
{
this.pageKwd = pageKwd;
}
public String getPageDesc()
{
return pageDesc;
}
#Field("pageDesc")
public void setPageDesc(String pageDesc)
{
this.pageDesc = pageDesc;
}
public int getSiteId()
{
return siteId;
}
#Field("siteId")
public void setSiteId(int siteId)
{
this.siteId = siteId;
}
public int getApplicationId()
{
return applicationId;
}
#Field("applicationId")
public void setApplicationId(int applicationId)
{
this.applicationId = applicationId;
}
public Date getPageCreatedTime()
{
return pageCreatedTime;
}
#Field("pageCreatedTime")
public void setPageCreatedTime(Date pageCreatedTime)
{
this.pageCreatedTime = pageCreatedTime;
}
public Date getPageUpdatedDate()
{
return pageUpdatedDate;
}
#Field("pageUpdatedDate")
public void setPageUpdatedDate(Date pageUpdatedDate)
{
this.pageUpdatedDate = pageUpdatedDate;
}
public String getWebContentData()
{
return webContentData;
}
#Field("webContentData")
public void setWebContentData(String webContentData)
{
this.webContentData = webContentData;
}
public String getWebContentType()
{
return webContentType;
}
#Field("webContentType")
public void setWebContentType(String webContentType)
{
this.webContentType = webContentType;
}
public String getCategory() {
return category;
}
#Field("category")
public void setCategory(String category) {
this.category = category;
}
}
I haven't created any schema.xml file or edited the existing schema.xml file. I am manually setting the values for each field in the POJO and adding it to the Solr index using my application as follows:
solrClient = new HttpSolrClient.Builder(solrUrl).build();
solrClient.setParser(new XMLResponseParser());
WebContentSearchHB searcHB = new WebContentSearchHB();
//codes to set data
solrClient.addBean(searcHB);
solrClient.commit();
I have also added the following maven dependency to my pom.xml file
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>6.5.1</version>
</dependency>
One of my fields in the WebContentSearchHB class, named category will contain a comma separated string of ids of various categories for that content.
A sample data would look like the one shown below:
[
{"pageTitle":["Test page"],
"pageKwd":["Test page"],
"pageDesc":["Test page"],
"applicationId":[1],
"siteId":[5],
"category":["2,6,7,8"],
"pageCreatedTime":["2017-02-17T05:58:19.648Z"],
"pageUpdatedDate":["2017-06-12T03:46:45.489Z"],
"webContentDefinitionId":[4947],
"webContentType":["simplewebcontent.html"],
"id":"717821d9-989e-4c4f-b66a-8b5185ed88ca",
"webContentData":"test"],
"_version_":1570012287149801472}
]
here there are multiple categories added as comma seperated values. Now when I try search for the data in the catagory field as follows:
http://localhost::8983/solr/swcm_qa/select?indent=on&q=category:7*&wt=json
no data is returned. But if I search as follows,
http://localhost::8983/solr/swcm_qa/select?indent=on&q=category:2*&wt=json
All rows where 2appears as the first value in the comma separated string is returned. How can I search for a string from among the comma separated values in the category field? Also, how can I specify if the field is storing multiple values as comma separated string in the #Field annotation?

In category field "2,6,7,8" is indexed as single string
category:["2,6,7,8"]
It should be like
category:["2","6","7","8"]
Either you should apply filter to that category field before indexing so that it stores individual numeric value into the field with ,as delimiter
OR
modify query like q=category:*7*

Related

How to store a List of a class object into MySql using Spring boot

I want to store a List of class : RestApiResponse into MySql. But getting below error:
org.hibernate.HibernateException: Could not determine a type for class: com.try.sreapi.beans.RestApiResponse
Below are my classes:
Entity class : SREAPITestingHistory.java
#NamedQueries(#NamedQuery(name="getSREAPITestHistory.findAll", query="SELECT a FROM SREAPITestingHistory a"))
#SqlResultSetMapping(name="sreapitestinghistoryres",
entities=#EntityResult(entityClass=SREAPITestingHistory.class))
#Entity
#Table(name="sreapi_testing_history_details")
#Transactional
public class SREAPITestingHistory implements Serializable{
private static final long serialVersionUID = -7221709766109001257L;
#Id
#Column(name="request_time")
private String request_time;
#Column(name="req_id")
private String req_id;
#Column(name="app_name")
private String app_name;
#Column(name="request_name")
private String request_name;
#Lob
#Column(name="response_body")
private List<RestApiResponse> response;
public String getRequest_time() {
return request_time;
}
public void setRequest_time(String request_time) {
this.request_time = request_time;
}
public String getReq_id() {
return req_id;
}
public void setReq_id(String req_id) {
this.req_id = req_id;
}
public String getApp_name() {
return app_name;
}
public void setApp_name(String app_name) {
this.app_name = app_name;
}
public String getRequest_name() {
return request_name;
}
public void setRequest_name(String request_name) {
this.request_name = request_name;
}
public List<RestApiResponse> getResponse() {
return response;
}
public void setResponse(List<RestApiResponse> response) {
this.response = response;
}
}
Repository Class: SREAPITestingRepository.java
#Repository
public interface SREAPITestingRepository extends CrudRepository< SREAPITestingHistory, String> {
#Modifying
#Transactional
#Query(value="INSERT into sreapi_testing_history_details (request_time,req_id,app_name,request_name,response_body)"+ "VALUES (:request_time,:req_id,:app_name,:request_name,:response_body)", nativeQuery = true)
public void setApiTestHistoryDetails(#Param("request_time") String request_time,#Param("req_id") String req_id,#Param("app_name") String app_name,#Param("request_name") String request_name,#Param("response_body") List<RestApiResponse> response_body);
}
When I am trying to add values for response_body which is actually a List of RestApiResponse class and I am getting Could not determine a type for class: com.try.sreapi.beans.RestApiResponse exception
From Official doc
A Lob may be either a binary or character type.
The Lob type is inferred from the type of the persistent field or
property, and except for string and character-based types defaults to
Blob.
Example 1:
#Lob #Basic(fetch=LAZY) #Column(name="REPORT")
String report;
Example 2:
#Lob #Basic(fetch=LAZY) #Column(name="EMP_PIC",
columnDefinition="BLOB NOT NULL") protected byte[] pic;
So you can convert your list of data into json string or bytes to store.

Randomize result from Elasticsearch using NativeSearchQueryBuilder

Hi I am new ElasticSearch, I am using spring data. I have 2 API which saves data in article and discourse model using elastic search, now when a client app makes a API call for both article and discourse search it gives all article first and then discourse data. but i want to randomize the response how can i do that?
my article model class as follows
#AllArgsConstructor
#Data
#Document(indexName="articles", createIndex=true)
public class Article implements ITResult {
private String id;
private String hostContentId;
private String title;
private List<String> categories;
private String searchResultId;
#Override
public String getSummary() {
return excerpt;
}
#Override
public ContentType getContentType() {
return ContentType.ARTICLE;
}
#Override
public String getHostContentId() {
return hostContentId;
}
#Override
public String getUrl() {
return link;
}
#Override
public String getSearchResultId() {
return searchResultId;
}
public void setSearchResultId(String searchResultId) {
this.searchResultId = searchResultId;
}
}
I have done the following
SearchQuery query = new NativeSearchQueryBuilder().withIndices("articles","course")
.withPageable(new PageRequest(offset,limit))
.withFilter(multiMatchQuery(string, new String[] { "title", "excerpt", "author_name", "link"}))
.build();

Null columns are created on either tables when accessing data using Spring Data JPA

I am new to Spring Data JPA and Hibernate. By looking at different examples I built a working model for CRUD operations on one entity, I am having trouble in joining two tables to extract AF_NAME using AF_ID from another table which is Foreign key. A null column is created with the names of and while accessing, null is returned.please check if I am following preocedure for joins and point me to any tutorial know.
I followed this solution and still there is no progress.
#Entity
#Configuration
#EnableAutoConfiguration
#Table(name = "AFF_CONFIG")
public class AFF_CONFIG implements Serializable {
#Id
#Column(name = "AFF_CONFIG_ID")
private String AFF_CONFIG_ID;
#Column(name = "AFF_ID")
private String AFF_ID;
#Column(name = "CH_ID")
private String CH_ID;
#Column(name = "M_ID")
private Long M_ID;
#Column(name = "KEY")
private String KEY;
#Column(name = "VALUE")
private String VALUE;
#Column(name = "SYSTEM")
private String SYSTEM;
private AFF aff;
#LazyCollection(LazyCollectionOption.TRUE)
#ManyToOne
#JoinColumn(name = "AFF_ID")
public AFF getAff() {
return aff;
}
public void setAffiliate(AFF aff) {
this.aff = aff;
}
public String getAFF_CONFIG_ID() {
return AFF_CONFIG_ID;
}
public void setAFF_CONFIG_ID(String aFF_CONFIG_ID) {
AFF_CONFIG_ID = aFF_CONFIG_ID;
}
public String getAFF_ID() {
return AFF_ID;
}
public void setAFF_ID(String aFF_ID) {
AFF_ID = AFF_ID;
}
public String getCH_ID() {
return CH_ID;
}
public void setCHANNEL_ID(String cH_ID) {
CH_ID = cH_ID;
}
public Long getM_ID() {
return M_ID;
}
public void setM_ID(Long m_ID) {
M_ID = m_ID;
}
public String getKEY() {
return KEY;
}
public void setKEY(String kEY) {
KEY = kEY;
}
public String getVALUE() {
return VALUE;
}
public void setVALUE(String vALUE) {
VALUE = vALUE;
}
public String getSYSTEM() {
return SYSTEM;
}
public void setSYSTEM(String sYSTEM) {
SYSTEM = sYSTEM;
}
Second entity is:
#Entity
#Table(name = "AFF")
public class AFF implements Serializable {
#Column(name = "AFF_NAME")
private String AFF_NAME;
#Column(name = "AFF_CODE")
private String AFF_CODE;
#Id
#Column(name = "AFF_ID")
private String AFF_ID;
private Set<AFF_CONFIG> someAff = new HashSet<AFF_CONFIG>();
#LazyCollection(LazyCollectionOption.TRUE)
#OneToMany(cascade = CascadeType.ALL, mappedBy = "aff")
public Set<AFF_CONFIG> getSomeAff() {
return someAff;
}
public void setSomeAff(Set<AFF_CONFIG> someAff) {
this.someAff = someAff;
}
public String getAFF_ID() {
return AFF_ID;
}
public void setAFF_ID(String aFF_ID) {
AFF_ID = aFF_ID;
}
public String getAFF_NAME() {
return AFF_NAME;
}
public void setAFF_NAME(String aFF_NAME) {
AFF_NAME = aFF_NAME;
}
public String getAFF_CODE() {
return AFF_CODE;
}
public void setAFF_CODE(String aFF_CODE) {
AFF_CODE = aFF_CODE;
}
Since this is many to one relation I created set type in one and object type in another as defined in other places.Created a repository by extending crud and added a query. Excise the bunch of different annotations, I included them in hoping to solve the null entry.
#Repository
public interface MarketRepository extends CrudRepository<AFF_CONFIG,String> {
Page<AFF_CONFIG> findAll(Pageable pageable);
#Query("Select a,b from AFF_CONFIG a, AFF b where a.AFF_ID = b.AFF_ID" )
public List<AFF_CONFIG> getAffData();
}
the applicatoin is working fine even after some tinkering until I Included these annotations. Now there is this error:
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.Set, at table: aff.
I solved the issue with the help of my Supervisor. Looks like we have to follow naming specifications for Class and variables. And one more correction is to remove collection type object and change it to just object (removed set in aff class).I will post the corrected later, to compare and contrast.

Make input parameter mandatory JAX-WS

Input paramter to my webservice method is an Object of Class AddSingleDocRequest. This class contains all the input fields as class instance variable with their getter and setter. I want to make some of the input fields mandatory. What is the best way to achieve this ?
Following is the code snippet:
**//webservice method
public String uploadDoc(AddSingleDocRequest request)
{
}
**//Request Class**
public class AddSingleDocRequest
{
private String sFilepath;
private String sDataClass;
public void setDataClassName(String dataClassName)
{
this.sDataClass= dataClassName;
}
public String getDataClassName() {
return sDataClass;
}
public void setFilePath(String filePath)
{
this.sFilepath=filePath;
}
public String getFilePath()
{
return sFilepath;
}
}
I want to make sFilePath parameter as mandatory.
Add the next JAX-B annotations:
#XmlType(name = "AddSingleDocRequestType", propOrder = {
"sFilepath", "sDataClass"
})
public class AddSingleDocRequest {
#XmlElement(name = "sFilepath", required = true)
private String sFilepath;
#XmlElement(name = "sDataClass", required = false)
private String sDataClass;
public void setDataClassName(String dataClassName) {
this.sDataClass = dataClassName;
}
public String getDataClassName() {
return sDataClass;
}
public void setFilePath(String filePath) {
this.sFilepath = filePath;
}
public String getFilePath() {
return sFilepath;
}
}
See more in Using JAXB to customize mapping for JAX-WS web services.

NullPointerException #one-to-one mapping

Hi all I've a small problem to map one-to-one using JPA 2 persistence with EclipseLink vendor and maybe any of you will be able to help.
I want to map one table with another but the field in second table is optional. So I've created #Entity for the first table:
Amp class
private AmpApInfo ampApInfo;
private String apid;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
public String getApid() {
return this.apid;
}
public void setApid(String apid) {
this.apid = apid;
}
#OneToOne
#JoinColumn(name="apid")
public AmpApInfo getAmpApInfo() {
return this.ampApInfo;
}
public void setAmpApInfo(AmpApInfo ampApInfo) {
this.ampApInfo = ampApInfo;
}
and #Entity for the second table
AmpApInfo class
private String apid;
private Amp amp;
private String prodOrderNo;
public AmpApInfo() {
}
#OneToOne(optional=true, mappedBy="ampApInfo")
public Amp getAmp() {
return this.amp;
}
public void setAmp(Amp amp) {
this.amp = amp;
}
#Id
public String getApid() {
return apid;
}
public void setApid(String apid) {
this.apid = apid;
}
#Column(name="prod_order_no")
public String getProdOrderNo() {
return this.prodOrderNo;
}
public void setProdOrderNo(String prodOrderNo) {
this.prodOrderNo = prodOrderNo;
}
Now when I want to find prodOrderNo like
public Amp selectProdInfo(String name) {
// TODO Auto-generated method stub
Amp amp = Transactions.getEntityManager().find(Amp.class, name.trim());
System.out.println("order number" + amp.getAmpApInfo().getProdOrderNo());
return amp;
}
I'm expecting to get null cos its not there but I'm getting java.lang.NullPointerException on the line
System.out.println("order number" + amp.getAmpApInfo().getProdOrderNo());
Any one can help???
Either amp is null or amp.getAmpApInfo() is returning null, and you are trying to call methods on them.

Categories

Resources