Switch from Java to REST API and use XContent builders?


(fucema) #1

Is it possible to leverage the java xcontent builders to form json
strings that can be used to interact with the REST API?

I am trying to avoid manually marshalling from java objects to json
strings if the elastic search java api can do this already. If not I
will most likely use the Jackson JSON tools to form the json.

Cheers,
Seon


(Shay Banon) #2

Yes, at the end those builders can create either binary or string
representation. But, they don't provide (yet) a way to marshal / unmarshal
objects. In this case, I would suggest you use jackson to build the json and
index it in elasticsearch.

-shay.banon

On Wed, Aug 11, 2010 at 11:32 PM, fucema fucema@gmail.com wrote:

Is it possible to leverage the java xcontent builders to form json
strings that can be used to interact with the REST API?

I am trying to avoid manually marshalling from java objects to json
strings if the elastic search java api can do this already. If not I
will most likely use the Jackson JSON tools to form the json.

Cheers,
Seon


(fucema) #3

Ok thanks Shay.

My use case involves integrating ElasticSearch into Hibernate running
within Spring.

I have working code that integrates ES seamlessly with Hibernate using
the existing hibernate search framework (which by default hooks into
lucene via directory providers). My code leveraged the ES Java API to
make this happen mostly pain free, but now I have a requirement to
communicate with ES via the REST API.

Just to be clear, what you are saying is I should skip the builders
entirely and just use Jackson to facilitate communicating with the ES
REST API?

  • Seon

(Shay Banon) #4

Now I am confused a bit ;). If you used the native Java API, that menas you
built the xcontent (json) yourself from the object? If so, you can reuse the
same code with the REST API. Not sure why you need to move and use the REST
API, if its because the need of not using the elasticsearch jar in the
application, then the xcontent builders will not be available... .

Is the hibernate search integration code open somewhere?

-shay.banon

On Wed, Aug 11, 2010 at 11:58 PM, fucema fucema@gmail.com wrote:

Ok thanks Shay.

My use case involves integrating ElasticSearch into Hibernate running
within Spring.

I have working code that integrates ES seamlessly with Hibernate using
the existing hibernate search framework (which by default hooks into
lucene via directory providers). My code leveraged the ES Java API to
make this happen mostly pain free, but now I have a requirement to
communicate with ES via the REST API.

Just to be clear, what you are saying is I should skip the builders
entirely and just use Jackson to facilitate communicating with the ES
REST API?

  • Seon

(fucema) #5

Sorry for the confusion. My code is not open-sourced yet, although my
company is not against making it open.

The reason I am moving to the REST API is because I do not want to
start an ES Node in this JVM. So I am using the XContent wherever
possible, but communicating with ES through http (and not a java Node
instance).

Here's some working code snippets for indexing, the commented out code
was connecting to ES via no-data node, whereas the working code now
uses
a Spring rest client to speak with ES' REST api.

public void onAdd(final AddLuceneWork work, final String index, final

String type) {
final String id = work.getIdInString();
try {
BinaryXContentBuilder contentBuilder = jsonBuilder().startObject();
...
contentBuilder.endObject();
IndexRequest indexRequest =
indexRequest(index).type(type).id(id).source(contentBuilder);

// node.client().index(indexRequest, new
ActionListener() {
// @Override
// public void onResponse(IndexResponse indexResponse) {
// log.info("Successful async index [" + index + "]["

  • id + "]");
    // }
    //
    // @Override
    // public void onFailure(Throwable t) {
    // log.warn("Failed to index [" + index + "][" + id +
    "]", t);
    // }
    // });

          	restTemplate.put(serverBaseUrl + INDEX_URI,
    

contentBuilder.string(), index, type, id);

I am working on getting the search facilities working through the REST
api. Here is some code snippet that is currently broken.
Unfortunately, I cannot use an XContentQueryBuilder instance to get a
String representation of the query. This is not a big deal however,
and I'll just form the search query body by hand probably.

public Page<Photo> searchPhotos(XContentQueryBuilder queryBuilder,

int pageNum, int pageSize) {
// results start from index 0
int from = pageNum <= 0 ? 0 : (pageNum - 1) * pageSize;

	String query = queryBuilder.toString();
	String response = restTemplate.getForObject(serverBaseUrl + "/

{index}/{type}/_search/?q={query}&from={from}&size={size}",
String.class, index, type, query, from, pageSize);

// SearchResponse response =
// node.client()
// .search(
// searchRequest(index)
// .types(type)
// .searchType(SearchType.DEFAULT)
// .source(searchSource().query(queryBuilder).from(from).size(pageSize).explain(false))
// ).actionGet();
//
// if (response.getHits().getHits().length > 0) {
// Collection idlist = new ArrayList();
// for (SearchHit hit : response.getHits().getHits()) {
// try {
// idlist.add(Long.valueOf(hit.getId()));
// } catch (NumberFormatException e) {
// // Defensive try/catch ... should never reach here.
// log.error("Cannot cast string value [" + hit.getId() + "] to a
Long");
// }
// }
// if (!idlist.isEmpty()) {
// Query hibQuery =
sessionFactory.getCurrentSession().createQuery("from Photo where id in
(:idlist)").setParameterList("idlist", idlist);
// return new GenericPage(hibQuery.list(), pageNum,
pageSize, response.getHits().getTotalHits());
// }
// }
// Default, return empty page with zero results.
return new GenericPage(Collections.EMPTY_LIST, pageNum,
pageSize, 0);
}


(Shay Banon) #6

In this case, you should be able to reuse the xcontent builder. But, if you
don't want to start a (client) node within the app, you can always use the
transport client, which is more lightweight (does not join the cluster) and
provide the full API the node client provides (its the same Client
interface).

-shay.banon

On Thu, Aug 12, 2010 at 12:25 AM, fucema fucema@gmail.com wrote:

Sorry for the confusion. My code is not open-sourced yet, although my
company is not against making it open.

The reason I am moving to the REST API is because I do not want to
start an ES Node in this JVM. So I am using the XContent wherever
possible, but communicating with ES through http (and not a java Node
instance).

Here's some working code snippets for indexing, the commented out code
was connecting to ES via no-data node, whereas the working code now
uses
a Spring rest client to speak with ES' REST api.

   public void onAdd(final AddLuceneWork work, final String index,

final
String type) {
final String id = work.getIdInString();
try {
BinaryXContentBuilder contentBuilder =
jsonBuilder().startObject();
...
contentBuilder.endObject();
IndexRequest indexRequest =
indexRequest(index).type(type).id(id).source(contentBuilder);

// node.client().index(indexRequest, new
ActionListener() {
// @Override
// public void onResponse(IndexResponse
indexResponse) {
// log.info("Successful async index [" +
index + "]["

  • id + "]");
    // }
    //
    // @Override
    // public void onFailure(Throwable t) {
    // log.warn("Failed to index [" + index + "]["

  • id +
    "]", t);
    // }
    // });

                     restTemplate.put(serverBaseUrl + INDEX_URI,
    

contentBuilder.string(), index, type, id);

I am working on getting the search facilities working through the REST
api. Here is some code snippet that is currently broken.
Unfortunately, I cannot use an XContentQueryBuilder instance to get a
String representation of the query. This is not a big deal however,
and I'll just form the search query body by hand probably.

   public Page<Photo> searchPhotos(XContentQueryBuilder queryBuilder,

int pageNum, int pageSize) {
// results start from index 0
int from = pageNum <= 0 ? 0 : (pageNum - 1) * pageSize;

           String query = queryBuilder.toString();
           String response = restTemplate.getForObject(serverBaseUrl +

"/
{index}/{type}/_search/?q={query}&from={from}&size={size}",
String.class, index, type, query, from, pageSize);

// SearchResponse response =
// node.client()
// .search(
// searchRequest(index)
// .types(type)
//
.searchType(SearchType.DEFAULT)
//
.source(searchSource().query(queryBuilder).from(from).size(pageSize).explain(false))
// ).actionGet();
//
// if (response.getHits().getHits().length > 0) {
// Collection idlist = new ArrayList();
// for (SearchHit hit : response.getHits().getHits())
{
// try {
//
idlist.add(Long.valueOf(hit.getId()));
// } catch (NumberFormatException e) {
// // Defensive try/catch ... should
never reach here.
// log.error("Cannot cast string value
[" + hit.getId() + "] to a
Long");
// }
// }
// if (!idlist.isEmpty()) {
// Query hibQuery =
sessionFactory.getCurrentSession().createQuery("from Photo where id in
(:idlist)").setParameterList("idlist", idlist);
// return new
GenericPage(hibQuery.list(), pageNum,
pageSize, response.getHits().getTotalHits());
// }
// }
// Default, return empty page with zero results.
return new GenericPage(Collections.EMPTY_LIST,
pageNum,
pageSize, 0);
}


(James Cook) #7

Is it necessary to seed the transport client with addresses, or is there a
way for it to auto-detect?

I am using a non-data node now, but I would opt for a transport client if it
is lighter and/or faster.

On Wed, Aug 11, 2010 at 5:35 PM, Shay Banon shay.banon@elasticsearch.comwrote:

In this case, you should be able to reuse the xcontent builder. But, if you
don't want to start a (client) node within the app, you can always use the
transport client, which is more lightweight (does not join the cluster) and
provide the full API the node client provides (its the same Client
interface).

-shay.banon

On Thu, Aug 12, 2010 at 12:25 AM, fucema fucema@gmail.com wrote:

Sorry for the confusion. My code is not open-sourced yet, although my
company is not against making it open.

The reason I am moving to the REST API is because I do not want to
start an ES Node in this JVM. So I am using the XContent wherever
possible, but communicating with ES through http (and not a java Node
instance).

Here's some working code snippets for indexing, the commented out code
was connecting to ES via no-data node, whereas the working code now
uses
a Spring rest client to speak with ES' REST api.

   public void onAdd(final AddLuceneWork work, final String index,

final
String type) {
final String id = work.getIdInString();
try {
BinaryXContentBuilder contentBuilder =
jsonBuilder().startObject();
...
contentBuilder.endObject();
IndexRequest indexRequest =
indexRequest(index).type(type).id(id).source(contentBuilder);

// node.client().index(indexRequest, new
ActionListener() {
// @Override
// public void onResponse(IndexResponse
indexResponse) {
// log.info("Successful async index [" +
index + "]["

  • id + "]");
    // }
    //
    // @Override
    // public void onFailure(Throwable t) {
    // log.warn("Failed to index [" + index +
    "][" + id +
    "]", t);
    // }
    // });

                     restTemplate.put(serverBaseUrl + INDEX_URI,
    

contentBuilder.string(), index, type, id);

I am working on getting the search facilities working through the REST
api. Here is some code snippet that is currently broken.
Unfortunately, I cannot use an XContentQueryBuilder instance to get a
String representation of the query. This is not a big deal however,
and I'll just form the search query body by hand probably.

   public Page<Photo> searchPhotos(XContentQueryBuilder queryBuilder,

int pageNum, int pageSize) {
// results start from index 0
int from = pageNum <= 0 ? 0 : (pageNum - 1) * pageSize;

           String query = queryBuilder.toString();
           String response = restTemplate.getForObject(serverBaseUrl +

"/
{index}/{type}/_search/?q={query}&from={from}&size={size}",
String.class, index, type, query, from, pageSize);

// SearchResponse response =
// node.client()
// .search(
// searchRequest(index)
// .types(type)
//
.searchType(SearchType.DEFAULT)
//
.source(searchSource().query(queryBuilder).from(from).size(pageSize).explain(false))
// ).actionGet();
//
// if (response.getHits().getHits().length > 0) {
// Collection idlist = new ArrayList();
// for (SearchHit hit : response.getHits().getHits())
{
// try {
//
idlist.add(Long.valueOf(hit.getId()));
// } catch (NumberFormatException e) {
// // Defensive try/catch ... should
never reach here.
// log.error("Cannot cast string
value [" + hit.getId() + "] to a
Long");
// }
// }
// if (!idlist.isEmpty()) {
// Query hibQuery =
sessionFactory.getCurrentSession().createQuery("from Photo where id in
(:idlist)").setParameterList("idlist", idlist);
// return new
GenericPage(hibQuery.list(), pageNum,
pageSize, response.getHits().getTotalHits());
// }
// }
// Default, return empty page with zero results.
return new GenericPage(Collections.EMPTY_LIST,
pageNum,
pageSize, 0);
}


(Shay Banon) #8

Auto detect comes with the node client (and when you create a node client,
set the client to true, it causes it not be a data node, but add other
aspects to it (like not becoming a master)).

The idea of the transport client is to connect to one or more nodes, extract
from them the list of all the cluster members, and then perform operations
on the cluster. It will be slower than the node client since it will
probably need to do two hops when indexing. This logic is the same one you
would have had to implement with your REST client (give it a list of
addresses to connect to).

-shay.banon

On Thu, Aug 12, 2010 at 5:01 PM, James Cook jcook@tracermedia.com wrote:

Is it necessary to seed the transport client with addresses, or is there a
way for it to auto-detect?

I am using a non-data node now, but I would opt for a transport client if
it is lighter and/or faster.

On Wed, Aug 11, 2010 at 5:35 PM, Shay Banon shay.banon@elasticsearch.comwrote:

In this case, you should be able to reuse the xcontent builder. But, if
you don't want to start a (client) node within the app, you can always use
the transport client, which is more lightweight (does not join the cluster)
and provide the full API the node client provides (its the same Client
interface).

-shay.banon

On Thu, Aug 12, 2010 at 12:25 AM, fucema fucema@gmail.com wrote:

Sorry for the confusion. My code is not open-sourced yet, although my
company is not against making it open.

The reason I am moving to the REST API is because I do not want to
start an ES Node in this JVM. So I am using the XContent wherever
possible, but communicating with ES through http (and not a java Node
instance).

Here's some working code snippets for indexing, the commented out code
was connecting to ES via no-data node, whereas the working code now
uses
a Spring rest client to speak with ES' REST api.

   public void onAdd(final AddLuceneWork work, final String index,

final
String type) {
final String id = work.getIdInString();
try {
BinaryXContentBuilder contentBuilder =
jsonBuilder().startObject();
...
contentBuilder.endObject();
IndexRequest indexRequest =
indexRequest(index).type(type).id(id).source(contentBuilder);

// node.client().index(indexRequest, new
ActionListener() {
// @Override
// public void onResponse(IndexResponse
indexResponse) {
// log.info("Successful async index [" +
index + "]["

  • id + "]");
    // }
    //
    // @Override
    // public void onFailure(Throwable t) {
    // log.warn("Failed to index [" + index +
    "][" + id +
    "]", t);
    // }
    // });

                     restTemplate.put(serverBaseUrl + INDEX_URI,
    

contentBuilder.string(), index, type, id);

I am working on getting the search facilities working through the REST
api. Here is some code snippet that is currently broken.
Unfortunately, I cannot use an XContentQueryBuilder instance to get a
String representation of the query. This is not a big deal however,
and I'll just form the search query body by hand probably.

   public Page<Photo> searchPhotos(XContentQueryBuilder queryBuilder,

int pageNum, int pageSize) {
// results start from index 0
int from = pageNum <= 0 ? 0 : (pageNum - 1) * pageSize;

           String query = queryBuilder.toString();
           String response = restTemplate.getForObject(serverBaseUrl
  • "/
    {index}/{type}/_search/?q={query}&from={from}&size={size}",
    String.class, index, type, query, from, pageSize);

// SearchResponse response =
// node.client()
// .search(
// searchRequest(index)
// .types(type)
//
.searchType(SearchType.DEFAULT)
//
.source(searchSource().query(queryBuilder).from(from).size(pageSize).explain(false))
// ).actionGet();
//
// if (response.getHits().getHits().length > 0) {
// Collection idlist = new ArrayList();
// for (SearchHit hit :
response.getHits().getHits()) {
// try {
//
idlist.add(Long.valueOf(hit.getId()));
// } catch (NumberFormatException e) {
// // Defensive try/catch ... should
never reach here.
// log.error("Cannot cast string
value [" + hit.getId() + "] to a
Long");
// }
// }
// if (!idlist.isEmpty()) {
// Query hibQuery =
sessionFactory.getCurrentSession().createQuery("from Photo where id in
(:idlist)").setParameterList("idlist", idlist);
// return new
GenericPage(hibQuery.list(), pageNum,
pageSize, response.getHits().getTotalHits());
// }
// }
// Default, return empty page with zero results.
return new GenericPage(Collections.EMPTY_LIST,
pageNum,
pageSize, 0);
}


(fucema) #9

The transport client is an intriguing alternative for my use case. The
reason I am not using the Node is because of the multicast chattiness
on startup (it does join the cluster and send out multicast udp,
right?).

Does the transport client use strictly TCP only to communicate with
the nodes in the cluster?

I'll look into the transport client, as I really rather stick to the
Java API if possible. Thanks Shay.

  • Seon

On Aug 12, 10:24 am, Shay Banon shay.ba...@elasticsearch.com wrote:

Auto detect comes with the node client (and when you create a node client,
set the client to true, it causes it not be a data node, but add other
aspects to it (like not becoming a master)).

The idea of the transport client is to connect to one or more nodes, extract
from them the list of all the cluster members, and then perform operations
on the cluster. It will be slower than the node client since it will
probably need to do two hops when indexing. This logic is the same one you
would have had to implement with your REST client (give it a list of
addresses to connect to).

-shay.banon

On Thu, Aug 12, 2010 at 5:01 PM, James Cook jc...@tracermedia.com wrote:

Is it necessary to seed the transport client with addresses, or is there a
way for it to auto-detect?

I am using a non-data node now, but I would opt for a transport client if
it is lighter and/or faster.

On Wed, Aug 11, 2010 at 5:35 PM, Shay Banon shay.ba...@elasticsearch.comwrote:

In this case, you should be able to reuse the xcontent builder. But, if
you don't want to start a (client) node within the app, you can always use
the transport client, which is more lightweight (does not join the cluster)
and provide the full API the node client provides (its the same Client
interface).

-shay.banon

On Thu, Aug 12, 2010 at 12:25 AM, fucema fuc...@gmail.com wrote:

Sorry for the confusion. My code is not open-sourced yet, although my
company is not against making it open.

The reason I am moving to the REST API is because I do not want to
start an ES Node in this JVM. So I am using the XContent wherever
possible, but communicating with ES through http (and not a java Node
instance).

Here's some working code snippets for indexing, the commented out code
was connecting to ES via no-data node, whereas the working code now
uses
a Spring rest client to speak with ES' REST api.

   public void onAdd(final AddLuceneWork work, final String index,

final
String type) {
final String id = work.getIdInString();
try {
BinaryXContentBuilder contentBuilder =
jsonBuilder().startObject();
...
contentBuilder.endObject();
IndexRequest indexRequest =
indexRequest(index).type(type).id(id).source(contentBuilder);

// node.client().index(indexRequest, new
ActionListener() {
// @Override
// public void onResponse(IndexResponse
indexResponse) {
// log.info("Successful async index [" +
index + "]["

  • id + "]");
    // }
    //
    // @Override
    // public void onFailure(Throwable t) {
    // log.warn("Failed to index [" + index +
    "][" + id +
    "]", t);
    // }
    // });
                   restTemplate.put(serverBaseUrl + INDEX_URI,

contentBuilder.string(), index, type, id);

I am working on getting the search facilities working through the REST
api. Here is some code snippet that is currently broken.
Unfortunately, I cannot use an XContentQueryBuilder instance to get a
String representation of the query. This is not a big deal however,
and I'll just form the search query body by hand probably.

   public Page<Photo> searchPhotos(XContentQueryBuilder queryBuilder,

int pageNum, int pageSize) {
// results start from index 0
int from = pageNum <= 0 ? 0 : (pageNum - 1) * pageSize;

           String query = queryBuilder.toString();
           String response = restTemplate.getForObject(serverBaseUrl
  • "/
    {index}/{type}/_search/?q={query}&from={from}&size={size}",
    String.class, index, type, query, from, pageSize);

// SearchResponse response =
// node.client()
// .search(
// searchRequest(index)
// .types(type)
//
.searchType(SearchType.DEFAULT)
//
.source(searchSource().query(queryBuilder).from(from).size(pageSize).explai n(false))
// ).actionGet();
//
// if (response.getHits().getHits().length > 0) {
// Collection idlist = new ArrayList();
// for (SearchHit hit :
response.getHits().getHits()) {
// try {
//
idlist.add(Long.valueOf(hit.getId()));
// } catch (NumberFormatException e) {
// // Defensive try/catch ... should
never reach here.
// log.error("Cannot cast string
value [" + hit.getId() + "] to a
Long");
// }
// }
// if (!idlist.isEmpty()) {
// Query hibQuery =
sessionFactory.getCurrentSession().createQuery("from Photo where id in
(:idlist)").setParameterList("idlist", idlist);
// return new
GenericPage(hibQuery.list(), pageNum,
pageSize, response.getHits().getTotalHits());
// }
// }
// Default, return empty page with zero results.
return new GenericPage(Collections.EMPTY_LIST,
pageNum,
pageSize, 0);
}


(Shay Banon) #10

Yes, the transport client does strict TCP. Note, you can also configure the
node client to use unicast discovery to discover the nodes, it does not have
to be multicast.

-shay.banon

On Thu, Aug 12, 2010 at 7:51 PM, fucema fucema@gmail.com wrote:

The transport client is an intriguing alternative for my use case. The
reason I am not using the Node is because of the multicast chattiness
on startup (it does join the cluster and send out multicast udp,
right?).

Does the transport client use strictly TCP only to communicate with
the nodes in the cluster?

I'll look into the transport client, as I really rather stick to the
Java API if possible. Thanks Shay.

  • Seon

On Aug 12, 10:24 am, Shay Banon shay.ba...@elasticsearch.com wrote:

Auto detect comes with the node client (and when you create a node
client,
set the client to true, it causes it not be a data node, but add other
aspects to it (like not becoming a master)).

The idea of the transport client is to connect to one or more nodes,
extract
from them the list of all the cluster members, and then perform
operations
on the cluster. It will be slower than the node client since it will
probably need to do two hops when indexing. This logic is the same one
you
would have had to implement with your REST client (give it a list of
addresses to connect to).

-shay.banon

On Thu, Aug 12, 2010 at 5:01 PM, James Cook jc...@tracermedia.com
wrote:

Is it necessary to seed the transport client with addresses, or is
there a

way for it to auto-detect?

I am using a non-data node now, but I would opt for a transport client
if

it is lighter and/or faster.

On Wed, Aug 11, 2010 at 5:35 PM, Shay Banon <
shay.ba...@elasticsearch.com>wrote:

In this case, you should be able to reuse the xcontent builder. But,
if

you don't want to start a (client) node within the app, you can always
use

the transport client, which is more lightweight (does not join the
cluster)

and provide the full API the node client provides (its the same Client
interface).

-shay.banon

On Thu, Aug 12, 2010 at 12:25 AM, fucema fuc...@gmail.com wrote:

Sorry for the confusion. My code is not open-sourced yet, although my
company is not against making it open.

The reason I am moving to the REST API is because I do not want to
start an ES Node in this JVM. So I am using the XContent wherever
possible, but communicating with ES through http (and not a java Node
instance).

Here's some working code snippets for indexing, the commented out
code

was connecting to ES via no-data node, whereas the working code now
uses
a Spring rest client to speak with ES' REST api.

   public void onAdd(final AddLuceneWork work, final String

index,

final
String type) {
final String id = work.getIdInString();
try {
BinaryXContentBuilder contentBuilder =
jsonBuilder().startObject();
...
contentBuilder.endObject();
IndexRequest indexRequest =
indexRequest(index).type(type).id(id).source(contentBuilder);

// node.client().index(indexRequest, new
ActionListener() {
// @Override
// public void onResponse(IndexResponse
indexResponse) {
// log.info("Successful async index ["

index + "]["

  • id + "]");
    // }
    //
    // @Override
    // public void onFailure(Throwable t) {
    // log.warn("Failed to index [" + index

"][" + id +
"]", t);
// }
// });

                   restTemplate.put(serverBaseUrl + INDEX_URI,

contentBuilder.string(), index, type, id);

I am working on getting the search facilities working through the
REST

api. Here is some code snippet that is currently broken.
Unfortunately, I cannot use an XContentQueryBuilder instance to get a
String representation of the query. This is not a big deal however,
and I'll just form the search query body by hand probably.

   public Page<Photo> searchPhotos(XContentQueryBuilder

queryBuilder,

int pageNum, int pageSize) {
// results start from index 0
int from = pageNum <= 0 ? 0 : (pageNum - 1) *
pageSize;

           String query = queryBuilder.toString();
           String response =

restTemplate.getForObject(serverBaseUrl

  • "/
    {index}/{type}/_search/?q={query}&from={from}&size={size}",
    String.class, index, type, query, from, pageSize);

// SearchResponse response =
// node.client()
// .search(
// searchRequest(index)
// .types(type)
//
.searchType(SearchType.DEFAULT)
//

.source(searchSource().query(queryBuilder).from(from).size(pageSize).explai
n(false))

// ).actionGet();
//
// if (response.getHits().getHits().length > 0) {
// Collection idlist = new
ArrayList();

// for (SearchHit hit :
response.getHits().getHits()) {
// try {
//
idlist.add(Long.valueOf(hit.getId()));
// } catch (NumberFormatException e) {
// // Defensive try/catch ...
should

never reach here.
// log.error("Cannot cast string
value [" + hit.getId() + "] to a
Long");
// }
// }
// if (!idlist.isEmpty()) {
// Query hibQuery =
sessionFactory.getCurrentSession().createQuery("from Photo where id
in

(:idlist)").setParameterList("idlist", idlist);
// return new
GenericPage(hibQuery.list(), pageNum,
pageSize, response.getHits().getTotalHits());
// }
// }
// Default, return empty page with zero results.
return new GenericPage(Collections.EMPTY_LIST,
pageNum,
pageSize, 0);
}


(system) #11