The following code emits an elasticsearch query that is too verbose for my liking -
import org.elasticsearch.index.query.QueryBuilder;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
public class MyQueryPrinter {
public static void main(String[] args) {
QueryBuilder myQuery = termQuery("brand", "gucci");
System.out.println(myQuery.toString());
/* prints -
{
"term" : {
"brand" : {
"value" : "gucci",
"boost" : 1.0
}
}
}
*/
}
}
I'd like to print the shortest possible query json-
{
"term" : {
"brand" : "gucci"
}
}
The code also automatically "pretty-prints" (i.e. indents) the json.
How can I control how QueryBuilder is converted into a String?
Thanks!!
p.s. - I'm using Elasticsearch 5.5.3 via maven -
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.5.3</version>
</dependency>
Related
I have base config file x.json which is something like
{
"key-i" : "value-i",
"key-ii" : {
"key-ii-a" : "value-ii-a",
"key-ii-b" : {
"key-ii-b-1" : "value-ii-b-1",
"key-ii-b-2" : "value-ii-b-2"
}
}
}
and another env specific config file x_env.json which is something like
{
"key-ii" : {
"key-ii-b" : {
"key-ii-b-2" : "different-value-ii-b-2"
}
}
}
Now I want to overwrite only config present in x_env.json on top of x.json which should look like
{
"key-i" : "value-i",
"key-ii" : {
"key-ii-a" : "value-ii-a",
"key-ii-b" : {
"key-ii-b-1" : "value-ii-b-1",
"key-ii-b-2" : "different-value-ii-b-2"
}
}
}
This is only an example and x.json can be any json and how can I generically overwrite x_env.json on x.json for any json structure in Java.
I am using the gson library and following to parse
JsonParser.parseString(IOUtils.toString(ClassName.class.getResourceAsStream("x.json"))).getAsJsonObject();
I am using the JsonSmartJsonProvider and my JSON looks like this
{
"info": {
"clientCount": 1,
"compactorVersion": 2,
"processMonitor": {
"processList": [
{
"name": "java.exe",
"commandLine": "",
"pid": 6224
}
]
}
}
}
I'm trying to exclude "processList", but keep everything else. I've tried variations on $.info[?(# noneof ['processMonitor'])], but I always end up with "info" being empty in the response. Is it possible to use JsonPath to do this? The code that is used to do this looks like this:
DocumentContext document = JsonPath.using(CONFIGURATION).parse(json);
Map<String, Object> result = new HashMap<>();
paths.forEach((key, value) -> result.put(key, document.read(value)));
return result;
As mentioned, you are actually looking for a JSON transformation. JOLT is a common library to do just that. A solution can look like this:
import java.util.List;
import com.bazaarvoice.jolt.Chainr;
import com.bazaarvoice.jolt.JsonUtils;
public class MyJsonTransformer {
public static void main(String[] args) throws Exception {
List<Object> specs = JsonUtils.classpathToList("/spec.json");
Chainr chainr = Chainr.fromSpec(specs);
Object inputJSON = JsonUtils.classpathToObject("/input.json");
Object transformedOutput = chainr.transform(inputJSON);
System.out.println(JsonUtils.toPrettyJsonString(transformedOutput));
}
}
And a jolt remover spec file like this:
[
{
"operation": "remove",
"spec": {
"info": {
"processMonitor": {
"processList": ""
}
}
}
}
]
You can try JOLT online with your input and the spec above here. Pretty neat.
The JSON and spec can be defined inline as well. I have not tested this end to end.
I'd like to use the swaggerjson String, to define as a var in a html file.
private static BeanConfig beanConfig = new BeanConfig();
public EtelApplication() {
printPath();
beanConfig.setTitle("jim-rest");
beanConfig.setResourcePackage("com.mast.api");
beanConfig.setScan(true);
beanConfig.scanAndRead();
printSwaggerJson();
createSwaggerJsonFile();
}
private void printSwaggerJson() {
String swaggerjson = Json.pretty(beanConfig.getSwagger());
System.out.println(swaggerjson);
}
My html file has this script, where I would like to use the string
window.onload = function () {
const ui = SwaggerUIBundle({name */
url: "swagger.json", name: "jim-rest",
dom_id: '#swagger-ui',
validatorUrl: null,
deepLinking: true,
spec: swaggerjson, //this is where I would like to use the var.
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
})
window.ui = ui
}
is it possible to use swaggerjson directly like this?
I aplogise for the very simple question, I wasn't able to find a detailed answer when searching
how to implement below code in java using spring Data mongodb
db.profil.aggregate([
{ "$match": { "typ": "Organisation" } },
{ "$group": {
"_id": null,
"count": {
"$sum": { "$size": "$foos" }
}
} }
])
MongoDB has an Aggregation framework for Java to support all aggregation APIs.
Try following:
import static com.mongodb.client.model.Accumulators.*;
import static com.mongodb.client.model.Aggregates.*;
import static com.mongodb.client.model.Projections.*;
Bson match = match(eq("typ", "Organisation")));
Bson projection = new Document("$size", "$foos" );
Bson group = group("$_id", Accumulators.sum("count",projection));
MongoCursor<Document> cursor = collection.aggregate(asList(match, group)).iterator();
I have this HTTP response body to de-serialize:
String response = "result : {'url': u'https://somedomain/', 'fields': {'policy':
u'eyJjb25kaXRpb25zIjogW1siYfgfhudGVudC1sZjMyWiJ9', 'AWSAccessKeyId':
u'ASIccccccNA', 'x-amz-security-token': 'FQofgF', 'key': u'bbb.file',
'signature': u'rm9gdflkjfs='}}"
I am using the jackson.core (2.9.0) java package and lib (have also tried GSON) and get this error:
Exception in thread "main" com.fasterxml.jackson.core.JsonParseException:
Unrecognized token 'u': was expecting ('true', 'false' or 'null')
Deserialization code:
MyResponse deserializedResponse = new ObjectMapper()
.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true)
.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true)
.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true)
.readValue(response, MyResponse.class);
I have considered something like this but it feels like there should be a better / safer way:
String sanitizedResponse = response.replaceAll("u'", "'");
--
Using Java 1.8.
Any help appreciated.
As python caused this problem I think the best solution is to let python fix it ;-). Fortunately with jython you can stick with a pure java implementation.
First you need to add the jython standalone dependency in your pom.xml:
<dependencies>
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>2.7.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
(As you can see I also used apache commons io for my example so I added it as well)
I put your (invalid) json string into the text file "c:/temp/json.txt" which has the following content:
{'url': u'https://somedomain/', 'fields': {'policy':
u'eyJjb25kaXRpb25zIjogW1siYfgfhudGVudC1sZjMyWiJ9', 'AWSAccessKeyId':
u'ASIccccccNA', 'x-amz-security-token': 'FQofgF', 'key': u'bbb.file',
'signature': u'rm9gdflkjfs='}}
Now here is the code to read the json file, set up the Python Interpreter and handover the json to clean it up:
String content = FileUtils.readFileToString(new File("c:/temp/json.txt"), "UTF-8");
PythonInterpreter pi = new PythonInterpreter();
pi.exec("import json");
pi.exec("jsondata = " + content);
pi.exec("jsonCleaned = json.dumps(jsondata)");
PyObject jsonCleaned = (PyObject) pi.get("jsonCleaned");
System.out.println(jsonCleaned.asString());
pi.close();
The output is:
{"url": "https://somedomain/", "fields": {"signature": "rm9gdflkjfs=", "AWSAccessKeyId": "ASIccccccNA", "x-amz-security-token": "FQofgF", "key": "bbb.file", "policy": "eyJjb25kaXRpb25zIjogW1siYfgfhudGVudC1sZjMyWiJ9"}}
When you put that in a json validator (https://jsonlint.com/) you can see that it is a valid json now.
I can't tell if the performance is good enough for your use case so you have to test that out.
Remark:
In Eclipse there seems to be a bug with that jython version. It shows the following error:
console: Failed to install '': java.nio.charset.UnsupportedCharsetException: cp0.
Although it works nevertheless you can get rid of it by adding the following VM-Argument to your Run-Configuration:
-Dpython.console.encoding=UTF-8
Remark2: For the sake of completeness and to fully answer that question - here is how you can deserialize the cleaned JSON:
Add GSON Dependency to your pom.xml:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
Create representing classes:
Info class
public class Info {
private String url;
private Fields fields;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Fields getFields() {
return fields;
}
public void setFields(Fields fields) {
this.fields = fields;
}
}
Fields class
import com.google.gson.annotations.SerializedName;
public class Fields {
private String signature;
private String AWSAccessKeyId;
#SerializedName("x-amz-security-token")
private String x_amz_security_token;
private String key;
private String policy;
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
public String getAWSAccessKeyId() {
return AWSAccessKeyId;
}
public void setAWSAccessKeyId(String aWSAccessKeyId) {
AWSAccessKeyId = aWSAccessKeyId;
}
public String getX_amz_security_token() {
return x_amz_security_token;
}
public void setX_amz_security_token(String x_amz_security_token) {
this.x_amz_security_token = x_amz_security_token;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getPolicy() {
return policy;
}
public void setPolicy(String policy) {
this.policy = policy;
}
}
Finally add the following code after you get your cleaned JSON:
Gson gson = new Gson();
Info info = gson.fromJson(jsonCleaned.asString(), Info.class);
You need to use the following regex that replaces u' from beginning of word boundaries to replace with '
String regexPattern = "(\\bu')";