How to use ElasticSearch JSON DSL in Java? - java

I'm working on a springboot project and having some trouble with ElasticSearch.
The user will put some JSON-format elasticsearch DSL query strings in the database and they are black-box to me. What I need to do is get the query strings and use them so search information in elasticsearch.
In python, the DSL can be a parameter like this:
body = {
"query":{
"match_all":{}
}
}
es.search(index="my_index",doc_type="test_type",body=body)
How can I perform the search without knowing the details of the string and just using the JSON format query in Java?

I believe there are two ways to do it in modern ES client libraries. I haven't tried them myself, but first one seems to be pretty straightforward.
First one is using low-level client:
Request request = new Request("POST", "/index/_search");
request.setJsonEntity(jsonString);
Response response = client.performRequest(request);
Seems like it's enough just to push JSON as string into setJsonEntity, and you're already set.
Second one is to use high level client, and this gets tricky, though it can provide more robust API. As you might know, elasticsearch has concept of XContent, which is serialization/deserialization to/from different formats, including JSON. Theoretically, it is possible to create JsonXContentParser, which then can be used to instantiate SearchSourceBuilder:
SearchSourceBuilder.fromXContent(jsonXContentParser);
The problem is only that JsonXContentParser requires number of arguments to be instantiated, and i'm not sure how to properly create those dependencies.

Related

Using java classes in Play framework with Scala to be returned as Json Object

I have some java classes which were generated using axis wsdl2java. I want to use those classes to be returned in Json format, but i keep getting various error, such as cannot convert Incident Object to HttpResponse try to make it writable.
When tried using Writable it asks me to check if it have apply method.
Is there any swift way i can use java classes as is, without going through hassle of making it case classes.
You try to render a class directly with Ok(MyClass()) and this is not possible. You have to render it as Json or String or any Writable. Json is probably the best choice. You should use a library like play-json, circe or one of the several others and render you response with Ok(Json.toJson(Myclass())) (for play-json) or equivalent.

How to convert thrift objects to readable string and convert it back?

Sometimes, we need to create some thrift objects in unit tests. We can do it by manually create object using Java code, like:
MyObj myObj = new MyObj();
myObj.setName("???");
myObj.setAge(111);
But which is not convenient. I'm looking for a way to create objects with some readable text.
We can convert thrift objects to JSON with TSimpleJSONProtocol, and get very readable JSON string, like:
{ "name": "???", "age": 111 }
But the problem is TSimpleJSONProtocol is write only, thrift can't read it back to construct an instance of MyObj.
Although there is a TJSONProtocol which supports to serialize and deserialize, but the generated JSON is not readable, it uses a very simplified JSON format and most of the field names are missing. Not convenient to construct it in tests.
Is there any way to convert thrift objects to readable string and also can convert it back? If TSimpleJSONProtocol supports converting back, which is just what I'm looking for
The main goal of Thrift is to provide efficient serialization and RPC mechanisms. What you want is something that is - at least partially - contrary to that. Human-readable data structures and machine processing efficiency are to a good extent conflicting goals, and Thrift favors the latter over the former.
You already found out about the TSimpleJson and TJson protocols and about their pros and cons, so there is not much to add. The only thing that is left to say is this: the protocol/transport stack of Thrift is simple enough.
This simplicity makes it possible to add another protocol based on your specific needs without much or overly complicated work. One could probably even write an XML protocol (if anyone really wants such bloatware) in short time.
The only caveat, especially vis-à-vis your specific case, is the fact that Thrift needs the field ID to deserialize the data. So you either need to store them in the data, or you need some other mechanism which is able to retrieve that field ID based on the field and structure names.

How to use Hazelcast with restful?

I want to use Hazelcast in my Java application, but I also have .net applications which need to get/set data to/from the Hazelcast cache. I thought to use the "rest" approach. I have 2 questions:
1) How can I post and get a complex type? If I have a Person object with fields name (String), age (Integer), birthDate (Date), and sex (Enum), how should I post this info and how should I parse person info?
2) I have a cached IMap<String, String>. After I post data "three" with key "3" from a Poster plugin, on the Java side map.get("3") returns something like:
RestValue{contentType='text/plain;charset=utf-8', value="three"}"
I expect this code to return just "three" without any cast operation.
I will be pleased if you give information about this issues.
Thanks in advance...
It sounds like you have a couple of different types of issues here with your current setup.
1) I don't have a good answer for this because I don't actually know much about rest clients in .net. You also may also get better results if you change your architecture as mentioned below.
2) It looks like the problem you have here is that you're just storing the raw request object(RestValue) in the IMap rather than storing the content of that object. Usually requests to a rest api contain more information than just the value sent to your server so you'll have to extract the value from the RestValue in your rest api. Hazelcast RestValue has a method called getValue(), so you should just be able to call getValue() which returns a byte[]. You should then just convert that byte[] to a String (or whatever datatype you prefer to store, maybe int in this case) and store the result in your IMap instead of just storing the entire RestValue object.
As far as having .net + java architecture, it may be best to run a Hazelcast-server node in whichever language you prefer and then have a .net hazelcast-client node and a java hazelcast-client node that are all connected to the same cluster. This way you can have all of your .net code run on your .net client completely separattd from your java infrastructure and communicate between the separate languages using hazelcast.

Elasticsearch Java API - fuzzy search with max_expansion

How can I translate the "more complex" fuzzy example from the QueryDSL guide into Java?
What I have so far is this: (Which works fine, but for example I'm unable to find the builder methods for "max_expansion", which would allow me to restrict the query)
QueryBuilders.fuzzyQuery("name", "kimchy")
Any pointers into the right direction are appreciated.
It supposed to be QueryBuilders.fuzzyQuery("name", "kimchy").maxExpansion(5). But, unfortunately, the maxExpansion() method is currently missing. So, until this pull request is merged, the only way to send this query is by expressing it directly in json. You can do it using XContentBuilder.
Construct a Lucene FuzzyQuery directly, then you can pass that option into a constructor arg.

Returning a value object to flex from java which contains two array of strings as it's properties

I amusing Flex for front end building. I have one doubt regarding sending two array of strings from java to flex.
How can I do that?
For example I have a value object defined like below.
class Test
{
String value1[]={"1","2","3"};
String value2[]={"narendra","mani","suresh","kane"};
//Getter and setters goes here
}
Can any one help me on this?
Thanks,
Narendra
This is really a matter of how do you want Flex to communicate with your Java layer, I think the closest to a turn key solution to this is using the BlazeDS jar on the server to do the ActionScript Message Format conversion between Java DTOs and Actionscript DTOs, basically how it works is you code up the Java side then you can have it generate the Java equivalent DTOs that will be tagged with Metadata so when the Java objects are serialized and sent across the wire the client has them as typed objects.
http://opensource.adobe.com/wiki/display/blazeds/BlazeDS
Alternatively you could expose the data as XML using a JSP to generate the XML then just using an HTTPService call to the JSP to get the XML data then since AS3 makes use of E4X parsing the XML into AS3 objects is very easy, lots of examples of doing this just search for e4x AS3 for examples.
Hope this helps,
Shaun

Categories