Accessing Payloads in Elasticsearch Suggestion - elasticsearch

I am currently using the Java API for Elasticsearch.
A suggestion query, returns multiple results 'Suggestion', which I want to be able to iterate over and access the variables. This is done by:
val builder = es.prepareSuggest("companies").addSuggestion(new CompletionSuggestionBuilder("companies").field("name_suggest").text(text).size(count()) )
val suggestResponse = builder.execute().actionGet()
val it = suggestResponse.getSuggest.iterator()
Now
while (it.hasNext()){
val info = it.next()
info.....
}
I need to be able to access info from the payloads from 'info'. An example of the return looks like:
{
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"companies": [
{
"text": "wells",
"offset": 0,
"length": 16,
"options": [
{
"text": "Wells Fargo",
"score": 123.0,
"payload": {
"industry_id": 130,
"id": 776,
"popularity": 123
}
},
{
"text": "Wells Real Estate Funds",
"score": 140.0,
"payload": {
"industry_id": 100,
"id": 778,
"popularity": 123
}
},
{
"text": "Wellstar Health System",
"score": 126.0,
"payload": {
"industry_id": 19,
"id": 1964,
"popularity": 123
}
}
]
}
]
}
When iterating through each suggestion, I seem unable to get the payload. Any ideas as to how I can do this?

To access the payloads, you have to iterate over the Option-Objects. (Right now, you are iterating over the suggestions)
import org.elasticsearch.search.suggest.Suggest.Suggestion
import org.elasticsearch.search.suggest.completion.CompletionSuggestion.Entry
...
// Get your "companies" suggestion
val suggestions: Suggestion[Entry] = suggestResponse.getSuggest.getSuggestion("companies")
val it = suggestions.getEntries.iterator()
// Iterate over all entries in the "company" suggestion
while(it.hasNext) {
val entry = it.next()
val optionsIt = entry.getOptions.iterator()
// Iterate over the options of the entry
while (optionsIt.hasNext) {
val option = optionsIt.next()
// As soon as you have the option-object, you can access the payload with various methods
val payloadAsMap = option.getPayloadAsMap
}
}
I found the information in the tests of ElasticSearch on Github

Related

how make a calculation with elastic document fields?

I need to make some calculation with each doc's some fields and then return it as response's part
I've written this
TermsAggregationBuilder subAggregation = AggregationBuilders
.terms("price")
.script(new Script(ScriptType.INLINE, "painless",
" int total = 0;\n" +
" for (int i = 0; i < 5; ++i) {\n" +
" total += doc['age'].value;\n" +
" }\n" +
" return total ;\n"
, Collections.emptyMap()));
NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
.withQuery(matchAllQuery())
.addAggregation(subAggregation)
.build();
SearchHits<Stories>
searchHits = elasticsearchOperations.search(nativeSearchQuery, Stories.class
, IndexCoordinates.of("long_stories"));
and this returns this one
{
"totalHits": 1,
"totalHitsRelation": "EQUAL_TO",
"maxScore": 1,
"scrollId": null,
"searchHits": [
{
"id": "44",
"score": 1,
"sortValues": [],
"content": {
"id": "44",
"innerId": 5,
"age": 44,
"salary": 433,
"mark": 10,
"state": "state",
"stores": [
{
"storiesId": "44",
"innerId": 1
},
{
"storiesId": "44b",
"innerId": 2
},
{
"storiesId": "44c",
"innerId": 3
}
],
"esh": null
},
"highlightFields": {}
}
],
"aggregations": {
"asMap": {
"price": {
"name": "price",
"metadata": null,
"buckets": [
{
"aggregations": {
"asMap": {},
"fragment": true
},
"keyAsString": "220",
"docCount": 1,
"docCountError": 0,
"key": "220",
"keyAsNumber": 220,
"fragment": true
}
],
"type": "sterms",
"docCountError": 0,
"sumOfOtherDocCounts": 0,
"fragment": true
}
},
"fragment": true
},
"empty": false
}
this response gives separate calculation I need it to be with above part ,and also if key which is 220 now if I had some another doc which would give the same answer then response would print 220 and doc count 2 I need it to be separately and in above response
like doc1 220 doc2 220 and in above response where actual data holds
Terms aggregation works as "group by".
So it will have only unique keys and documents clubbed under those keys. If you need it on per document basis use scripted field in query instead of aggregation.
With scripted field you will need to specify "source" to fetch rest of the document.
You can also explore runtime field in place of scripted field. It offer some benefits over scripted field
You can use script fields to access values in _source and return
calculated values based on a script valuation. Runtime fields have
these same capabilities, but provide greater flexibility because you
can query and aggregate on runtime fields in a search request. Script
fields can only fetch values.

Jmeter - how to return multiple ID(s) based on the array (match JSON path with array)

Having array as:
[France, Switzerland, Croatia, Spain, Brondby, Sonderjyske, CFR Cluj, Ujpest FC, Young Boys , Xamax, Bedford Town, Biggleswade Town]
Having JSON fetched from API call as (NOT full JSON provided)
{
"payload": [
{
"id": 104,
"externalId": "e5b93978-0960-4c01-a201-b15c9e6afb49",
"shortName": "FRA",
"name": "France",
"countryCode": "en",
"leagueId": 1,
"logoUrl": "http://www.example.com/logo.png"
},
{
"id": 110,
"externalId": "7f1f76c1-483c-4c14-b5f9-61e58a5d9328",
"shortName": "Swi",
"name": "Switzerland",
"countryCode": "en",
"leagueId": 1,
"logoUrl": "http://www.example.com/logo.png"
},
{
"id": 2189,
"externalId": "8d23300c-85f4-41b4-b0f1-65e5948f2c80",
"shortName": "Cro",
"name": "Croatia",
"countryCode": "en",
"leagueId": 1,
"logoUrl": "http://www.sdfgsdf.com/image.png"
}
],
"errorCode": 0,
"errorTimeStamp": null,
"errorMessage": null,
"hasError": false
}
For every single member of the array, I need to get its ID's.
I know how match for signle member using JSON path
But, how to fetch all the ID's based on the particullar array?
Given that you have this "array" in a JMeter Variable called array you can get all the IDs by adding a JSR223 PostProcessor and using the following Groovy code in the "Script" area:
vars.get('array').replace('[', '').replace(']', '').tokenize(',').each { country ->
def result = new groovy.json.JsonSlurper().parse(prev.getResponseData()).payload.find { entry -> entry.name == country.trim() }
if (result != null) {
log.info('Country: ' + country.trim() + ', id: ' + result.id)
}
}
Demo:
More information:
JsonSlurper
Apache Groovy - Parsing and producing JSON

How to save debug json to database in laravel?

I make a rest API with auth with api_token, and I use debugger by Lanin to show when the error happened.
If api_token is wrong the debug will show something like below
{
"error": "Unauthenticated.",
"debug": {
"database": {
"total": 1,
"items": [
{
"connection": "mysql",
"query": "select * from `users` where `api_token` = '630dcedd96aa370891b1649a972b577b2f262c90093b1903ae0a2ea63cf2c07cs' limit 1;",
"time": 2.89
}
]
},
"cache": {
"hit": {
"keys": [
"424f74a6a7ed4d4ed4761507ebcd209a6ef0937b"
],
"total": 1
},
"miss": {
"keys": [
"424f74a6a7ed4d4ed4761507ebcd209a6ef0937b",
"424f74a6a7ed4d4ed4761507ebcd209a6ef0937b:timer",
"424f74a6a7ed4d4ed4761507ebcd209a6ef0937b"
],
"total": 3
},
"write": {
"keys": [
"424f74a6a7ed4d4ed4761507ebcd209a6ef0937b:timer",
"424f74a6a7ed4d4ed4761507ebcd209a6ef0937b"
],
"total": 2
},
"forget": {
"keys": [],
"total": 0
}
},
"profiling": [
{
"event": "request-time",
"time": 0.2898838520050049
}
],
"memory": {
"usage": 11831808,
"peak": 11896088
}
}
}
and I want to save error log to the database. How to save and read data if I want to save this to the table database? I want to save the query
"debug": {
"database": {
"total": 1,
"items": [
{
"connection": "mysql",
**"query": "select * from `users` where `api_token` = '630dcedd96aa370891b1649a972b577b2f262c90093b1903ae0a2ea63cf2c07cs' limit 1;",
"time": 2.89**
}
]
},
With an appropriate model (Debug with "connection", "query" and "time" field), you could decode the json into an array and create the model from that.
Something like this :
$jsonArray = json_decode($rawJson, true);
$debug = Debug:create($jsonArray);

Immutable js updating a Map in a List

Pushing nested data into a Map inside a List
Can anyone tell me:
How do i push a task to either of these users (List items) ideally by specific user id?
Thanks in advance.
My code:
const initialState = Immutable.List([
Immutable.Map({
"id": 1,
"name": "Abe Bell",
"tasks": [
{
"id": 1,
"title": "Get haircut",
"status": false
}
]
}),
Immutable.Map({
"id": 2,
"name": "Chad Dim",
"tasks": [
{
"id": 2,
"title": "Get real job",
"status": false
}
]
})
])
First, the way you're building this structure, the tasks array will not be an immutable instance, I think that is not what you want, you can use Immutable.fromJS to transform all the nested arrays and maps into a Immutable instance.
The way your data is structured you'll have to navigate through the list of users and perform the update when the id matches.
One way of doing that is using map
const initialState = Immutable.fromJS([
{
"id": 1,
"name": "Abe Bell",
"tasks": [
{
"id": 1,
"title": "Get haircut",
"status": false
}
]
},
{
"id": 2,
"name": "Chad Dim",
"tasks": [
{
"id": 2,
"title": "Get real job",
"status": false
}
]
}
]);
let userId = 2;
let newState = initialState.map(user => {
if (user.get('id') !== userId) {
return user;
}
return user.update('tasks', tasks => {
return tasks.push(Immutable.fromJS({
id: 3,
title: "new task",
status: false
}))
});
});
Although this will do what you want,I think you should change your data to a map instead of a list if this kind of operation is something recurrent in your application. This will make things easier and faster.
const initialState = Immutable.fromJS({
"1": {
"id": 1,
"name": "Abe Bell",
"tasks": [
{
"id": 1,
"title": "Get haircut",
"status": false
}
]
},
"2": {
"id": 2,
"name": "Chad Dim",
"tasks": [
{
"id": 2,
"title": "Get real job",
"status": false
}
]
}
});
let userId = "2";
let newState = initialState.updateIn([userId, 'tasks'], tasks => {
return tasks.push(Immutable.fromJS({
id: 3,
title: "new task",
status: false
}));
});

Updating array elements that matches a specific criteria

Let's say I have the following array
var data = [{ id: 0, points: 1 }, { id: 1, points: 2 }]
I would like to update my table which contains
{
"doc-1": {
"id": "abcxyz123",
"entries": [
{ "id": 0, "points": 5 },
{ "id": 1, "points": 3 },
{ "id": 2, "points": 0 }
]
}
}
so that I add the points-field in the data array to the points-field for each element in the "entries" array in "doc-1" that matches the corresponding id in the data array. The end result would look like:
{
"doc-1": {
"id": "abcxyz123",
"entries": [
{ "id": 0, "points": 6 },
{ "id": 1, "points": 4 },
{ "id": 2, "points": 0 }
]
}
}
How do I go about to write such a query in ReQL?
I assume that the actual document in the table looks like this for now:
{
"id": "abcxyz123",
"entries": [{
"id": 0,
"points": 5
}, {
"id": 1,
"points": 3
}, {
"id": 2,
"points": 0
}]
}
That is without the doc-1 nesting.
Then your update can be done like this:
r.table('t1').update(
{
entries: r.row('entries').map(function(e) {
return r.do(r.expr(data)('id').indexesOf(e('id')), function(dataIndexes) {
return r.branch(
dataIndexes.isEmpty(),
e,
{
id: e('id'),
points: e('points').add(r.expr(data)(dataIndexes(0))('points'))
});
});
})
})
I'm using map to map over each entry in entries, and indexesOf to find the corresponding entry in data if it exists.
Note that this doesn't add new entries to the entries list, but only updates existing ones. Please let me know if you need to add new entries as well.
If your documents actually have the doc-1 field first, this query should do the job:
r.table('t1').update(
{ 'doc-1':
{
entries: r.row('doc-1')('entries').map(function(e) {
return r.do(r.expr(data)('id').indexesOf(e('id')), function(dataIndexes) {
return r.branch(
dataIndexes.isEmpty(),
e,
{
id: e('id'),
points: e('points').add(r.expr(data)(dataIndexes(0))('points'))
});
});
})
}
})

Resources