Reputation: 592
I'm testing Spring data with elasticSearch. The ES server is running on a remote server in tha same room.
I have one index created a day, under an alias. I'm trying to find a simple tweet. But when I try a findOne()
, it doesn't seem to work because it returns always null
.
Also, findAll(ids)
doesn't work because I'm using the alias, but I can't find in the documentation how to handle this.
What do I want to achieve ?
For the moment, simply retrieve a tweet with a given id_str
.
The count method works, the findOne doesn't
Here are my questions
What should I do to make findOne()
to work ?
Which way should I use to search on multiple indexes in this alias ?
Here is how the datas looks like in ES
{
"id_str" : "135131315100051",
"..." : "...",
"user" : {
"id_str" : "15843643228"
"..." : "..."
}
}
My model
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
@Document(indexName = "alias", type = "tweets")
public class Tweet
{
@Id
@Field(type = FieldType.String)
private String idStr;
public String getIdStr()
{
return idStr;
}
public void setIdStr(final String idStr)
{
this.idStr = idStr;
}
@Override
public String toString()
{
return "{ id_str : " + idStr + " }";
}
}
Alias is alias
, and indexes are alias_dd-mm-yyyy
My repository
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import com.thales.communications.osintlab.bigdata.webservices.models.Tweet;
public interface EsTweetRepository extends ElasticsearchRepository<Tweet, String>
{
Tweet findByIdStr(String idStr);
}
My test
@Test
public void shouldReturnATweet()
{
//lets try to search same record in elasticsearch
final Tweet tweet1 = tweetRepository.findOne("593768150975512576");
//final Tweet tweet = tweetRepository.findByIdStr("593897683661824000");
System.out.println("Count is " + tweet1);
//System.out.println("Count is " + tweetRepository.count());
// System.out.println(tweet.toString());
}
Of course, the tweet with the tested Id exists :). And the count()
is working fine.
Thanks for your help
EDIT
Here is a sample application of what I have : https://github.com/ogdabou/es-stackoverflow-sample
It seems that spring-data-elasticsearch is look for the field "_id" and not the field "id_str". Maybe because of method parsing (look there). I'm looking for a way to bind my json "id_str" attribute to my idStr java model.
Upvotes: 1
Views: 4436
Reputation: 592
What was the real issue
We set the _id
field of our tweet in Elasticsearch with the id
field given by twitter. But it saves it in another format ( eg 132 becomes 1.32E2)
When I'm going a findOne()
it is searching for a match with the Elasticsearch _id
field and not the id_str
I needed.
Solution
There, you have 2 commits, the first is the issue, the second the solution.
New repository
public interface EsTweetRepository extends ElasticsearchRepository<Tweet, String>
{
@Query("{\"bool\" : {\"must\" : {\"term\" : {\"id_str\" : \"?0\"}}}}")
Tweet findByIdStr(String idStr);
}
The model
@Document(indexName = "my_index_01", type = "tweets")
public class Tweet
{
// Elasticsearch object internal id. Look at field "_id"
@Id
private String id;
// Twitter internal id, saved under the "id_str" field
@Field(type = FieldType.String)
private String id_str;
@Field(type = FieldType.String)
private String text;
public String getId_str()
{
return id_str;
}
public void setId_str(final String id_str)
{
this.id_str = id_str;
}
public String getText()
{
return text;
}
public void setText(final String text)
{
this.text = text;
}
public String getId()
{
return id;
}
public void setId(final String id)
{
this.id = id;
}
@Override
public String toString()
{
return "{ _id : " + id + ", id_str : " + id_str + ", text : " + text + " }";
}
}
Upvotes: 3