Sorting on runtime calculated price value? - elasticsearch

we have day prices in our index. When user search for 7 nights we show the total price (7*nightprice = totalprice). We want to sort on total_price value.
The process and issue.
First we call our Index API to search appropriate accommodations by checking availabilities, restrictions etc. After that we get accommodations from our API, we pass searched accommodations ids to our Prices API to get they dynamic price. We are using ElasticSearch custom DSLs for our search. Now, we need to sort accommodations based on dynamic prices while keeping pagination on server side, but we can only sort accommodations that are visible on our first page because of dynamic prices are calculated in a separate API.
First call (Index API)
{
"id": "6555",
"type": "lodging",
"attributes": {
"id": 6555,
"name": "Villa Georges",
"h1": "Villa Georges | Stijlvol herenhuis in het hart van Rochefort in de Ardennen",
"h2": "",
"lodging_type": "villa",
"slug": "villa-georges",
"presentation": "as_standalone",
"child_name": "Villa Georges",
"country_name": "België",
"region_name": "Namen",
"address": "",
"latitude": 50.158783,
"longitude": 5.222144,
"adults": 8,
"children": null,
"infants": 1,
"price": 314,
"calculated_price": null,
"dynamic_price": null,
"short_desc": "",
"images": [
"https://imagesnice2stayeurope.s3.amazonaws.com/uploads/image/image/54634/Z6A0837-min.jpg",
"https://imagesnice2stayeurope.s3.amazonaws.com/uploads/image/image/54626/Z6A0753-min.jpg"
],
"average_rating": 0.0,
"created_at": "2021-02-01T00:00:00.000Z",
"updated_at": "2022-06-14T16:58:06.917Z",
"highlight_1": "Winkels en restaurants op loopafstand",
"highlight_2": "Mooie tuin rondom ",
"highlight_3": "Stijlvolle inrichting ",
"beds": 4,
"baths": 2,
"channel": "standard",
"particularities_text": "<ul>\r\n\t<li>Aankomst is flexibel met een minimum van 2 nachten </li>\r\n\t<li>Inchecken is mogelijk vanaf 14 uur, check-out voor 12 uur op de dag van vertrek</li>\r\n\t<li>Binnen mag er niet worden gerookt, buiten op de aangewezen plekken</li>\r\n\t<li>Kinderstoel, kinderbedje wordt klaargezet op aanvraag</li>\r\n\t<li>Huisdieren zijn niet toegestaan</li>\r\n\t<li>Zelf inchecken met sleutelkastje</li>\r\n</ul>\r\n",
"open_gds_property_id": null,
"open_gds_accommodation_id": null,
"including_text": "<ul>\r\n\t<li>gas/water/elektriciteit </li>\r\n\t<li>linnen, handdoeken, badjassen</li>\r\n\t<li>verzorgingsproducten</li>\r\n\t<li>wifi </li>\r\n\t<li>kinderbedje en stoel </li>\r\n</ul>\r\n",
"setting": 0.0,
"quality": 0.0,
"interior": 0.0,
"service": 0.0,
"communication": 0.0,
"total_reviews": 0,
"lowest_child_price": 314,
"total_available_childrens": 0,
"first_available_child_id": null
}
}
Second call (price API). The calculated_price is calculated on runtime.
{
"id": "6555",
"type": "cumulative_price",
"attributes": {
"id": 6555,
"name": "Villa Georges",
"calculated_price": 3325.0,
"price_valid": true,
"price_errors": {},
"dynamic_price": true,
"check_in": "2022-07-12",
"check_out": "2022-07-19",
"discount_price": 0.0,
"rent_price": 3325.0,
"cleaning_cost": 0.0,
"belongs_to_channel": false,
"optional_supplements": {
"data": []
},
"mandatory_supplements": {
"data": []
}
}
},
Any suggestions ?
best remco

Related

Elasticsearch - Sort By Distance Not Working?

I have an index where the records are stored in the following format:
"_source": {
"name": "ACME Pallets",
"about": null,
"slug": "acme-pallets",
"serviceAreas": [
{
"admin1": "usa",
"admin2": null,
"admin3": null,
"admin4": null,
"countryCode": "US",
"googlePlaceId": null,
"locality": null,
"selectedLevel": "admin1"
}
],
"id": "fadsflsjdfkk3234234",
"addresses": [
{
"address1": "4342 Dietrich Rd",
"address2": null,
"city": "San Antonio",
"countryCode": "US",
"latitude": 29.44122,
"longitude": -98.34404,
"primary": true,
"name": "office",
"postal": "78219",
"province": "TX",
"location": {
"lat": 29.44156,
"lon": -98.37704
}
}
]
}
I am trying to return results from this index where the records are sorted by distance to the search point I pass in. My sort config being passed in looks like this:
_geo_distance: {
'addresses.location': { lat: 31.75917, lon: -106.48749 },
order: 'asc',
unit: 'mi',
mode: 'min'
}
The results I receive back are not sorted according to distance. If I manually plot out the individual locations on a map and the search pin passed in, I can see that the sorting is out of order.
If I pass in a sorting config to my search to sort by alphabetically order or to sort by relevance (aka _score), the sorting returned is correct.
Does anyone know why ES might be returning my results incorrectly when sorting by distance?
addresses is an array in my index. Each object inside of addresses has a property called location of type geo_point.
From all the documentation that I've read, passing 'addresses.location': { lat: 31.75917, lon: -106.48749 } into the search should work, but it doesn't. ES should be smart enough to find the location geo point in each object and use that as the reference when calculating the distance. If there are more than one object inside of the addresses array, then ES by default should get the center point of all the objects inside of addresses and use that to calculate the distance from the search point.
In my case, I don't have any data where addresses has more than one object. I ended up creating a location geo_point property outside of the addresses property during index build and then passing in location: { lat: 31.75917, lon: -106.48749 } for the search. This made ES sort results based on distance correctly.
What my new index looks like with the added location property:
"_source": {
"name": "ACME Pallets",
"about": null,
"slug": "acme-pallets",
"serviceAreas": [
{
"admin1": "usa",
"admin2": null,
"admin3": null,
"admin4": null,
"countryCode": "US",
"googlePlaceId": null,
"locality": null,
"selectedLevel": "admin1"
}
],
"id": "fadsflsjdfkk3234234",
"addresses": [
{
"address1": "4342 Dietrich Rd",
"address2": null,
"city": "San Antonio",
"countryCode": "US",
"latitude": 29.44122,
"longitude": -98.34404,
"primary": true,
"name": "office",
"postal": "78219",
"province": "TX",
"location": {
"lat": 29.44156,
"lon": -98.37704
}
}
]
"location": {
"lat": 29.44156,
"lon": -98.37704
}
}

Validation of each field in JSON response using karate API

I want to validate particular fields in the response whether it is integer or float(ex: fullbathrooms field). I tried below code but getting match failed error. Could you please help here ?.....Thanks
Given path '/property-client'
And request {"address": <address>,"city": <city>,"state": <state>,"zipCode": <zipCode>}
When method post
Then status 200
And print response
And match response == {fullbathrooms:'#number'}
Examples:
|read('testFile1.csv')|
Error : match failed: EQUALS
Actual response:
{
"success": true,
"message": {
"version": "1.0",
"response": {
"id": "94568859",
"type": "express",
"responseheader": null,
"reportdata": {
"property": {
"source": null,
"type": null,
"dom": null,
"propertytype": "Single Family Residence",
"standardtype": null,
"address": {
"documentid": null,
"number": "150",
"directional": null,
"street": "BRIDGE",
"suffix": "RD",
"postdirectional": null,
"unit": "",
"city": "HILLSBOROUGH",
"state": "CA",
"zip": "94010",
"zipplus4": "6908",
"fulladdress": "150 BRIDGE RD, HILLSBOROUGH, CA 94010"
},
"info": {
"type": null,
"fips": "6081",
"county": "San Mateo",
"bedrooms": "5",
"bathrooms": "6.50",
"fullbathrooms": "6.50",
"totalrooms": "0",
"livingarea": "7750",
"totallivingarea": "7750",
"landarea": "41382",
"landareatype": null,
"pool": "true",
"landvalue": "6904800",
"improvementvalue": "3284414",
"assessedvalue": "10189214",
"assessedyear": "2021",
"taxvalue": "11746898",
"taxyear": "2021",
"deliquentyear": null,
"yearbuilt": "2011",
"propertytax": null,
"approxage": "11",
"parcelnumber": "032-400-110",
"titlecompany": null,
"geocode": {
"latitude": "37.563272",
"longitude": "-122.334442",
"geoqualitycode": ""
}
}
Please take some time to read the documentation: https://github.com/karatelabs/karate#match-contains
I'm not going to refer to your response dump (which by the way is not valid JSON), but give you a simple example. Please pay attention to the structure of your JSON. And note that the 6.50 is a string not a number in your response.
* def response = { "foo": { "bar": { "fullbathrooms": "6.50" } } }
* match response.foo.bar == { fullbathrooms: '#string' }
If you want to validate numbers within strings, please refer other answers, for example: https://stackoverflow.com/search?q=%5Bkarate%5D+number+regex

Orbeon: Static dropdown in repeated grid

I have a problem in repeated grid, I have a drop-down list where the users will choose what model they want.
Then I also have a JSON array which contains the model and other description of different cars.
How can I auto fill the appropriate JSON value to textField according to the chosen value in the drop-down list?
Like for example: The user chose the model Toyota, only the Toyota car model present in the JSON will be displayed at textField.
The form I've created is available at https://demo.orbeon.com/demo/fr/orbeon/builder/edit/3b1ebd5340007f245b34ccd468c36c188b376bd6. And here is the JSON:
{
"corppassUser": {
"corppassData": null,
"corppassEntity": {
"primaryActiviyDesc": "Marine insurance ",
"companyType": "A1",
"corppassPreviousNames": [],
"entityType": "LC",
"primaryActivityCode": "65121",
"businessExpiryDate": "",
"secondaryActivityCode": "93202",
"corppassShareholders": [
{
"allocation": 20000,
"personRef": {
"personName": "ANDY",
"nationality": "SG",
"id": 8,
"idno": "S6001111A"
},
"currency": "SGD",
"id": 3,
"entityRef": null,
"category": "1",
"shareType": "1"
},
{
"allocation": 10000,
"personRef": {
"personName": "TIMOTHY TAN",
"nationality": "SP",
"id": 6,
"idno": "S1112374E "
},
"currency": "SGD",
"id": 1,
"entityRef": null,
"category": "1",
"shareType": "1"
},
{
"allocation": 10000,
"personRef": {
"personName": "CLARISSA LIN",
"nationality": "SG",
"id": 7,
"idno": "S3212386E"
},
"currency": "SGD",
"id": 2,
"entityRef": null,
"category": "1",
"shareType": "1"
}
],
"uen": "T15LP0005A"
},
"id": 1
}
}

Paginate on grouped queries

I'm writing a system to follow cash flow. The users register transactions they made:
(transactions index screenshot)
but I need to get these transactions separated by date. I tried using an Request to index, but it doesn't looked the best pratice (it worked, however). Now I'm trying to do another aproach: retrieve all transactions and paginate them by date. Is it possible?
ps: maybe grouping by months helps? like:
$transactions = Transaction::all()->groupBy(function($transaction) {
return Carbon::parse($transaction->date)->format('m-Y');
});
this returns:
{
"03-2019": [
{
"id": 1,
"title": "Teste 1",
"date": "2019-03",
"user_id": 1,
"description": "Primeiro teste, com entrada de 1500 reais.",
"value": "1500.00",
"flow": 1,
"created_at": "2019-03-24 05:39:45",
"updated_at": "2019-03-24 05:39:45"
},
{
"id": 2,
"title": "Teste 2",
"date": "2019-03",
"user_id": 1,
"description": "Segundo teste, com saída de 500 reais.",
"value": "500.00",
"flow": 0,
"created_at": "2019-03-24 05:39:45",
"updated_at": "2019-03-24 05:39:45"
}
]
}
ps²: yeah, front-end is in brazilian portuguese and english isn't my native language.. :)
Try this out
<?php
use Illuminate\Pagination\LengthAwarePaginator;
$transactions = Transaction::all()->groupBy(function($transaction) {
return Carbon::parse($transaction->date)->format('m-Y');
});
//new LengthAwarePaginator($data,$countOfData,$perPage,$currentPage);
$transactions=new LengthAwarePaginator($transactions->forPage($currentPage,$perPage),$transactions->count(),$currentPage);
Hope it helps...

combining multiple geojson files w tsv and preserving property with topojson

i'm trying to do many things w topojson… combine 2 geojson files w 1 tsv, join on ELECT_DIV n NAME, promote that to the id, and keep 2012_POP from the tsv.
here's the command i'm using:
topojson -o electorates.json -e 2012_oz_population.tsv --id-property ELECT_DIV,NAME -p 2012_POP -s .0000005 --allow-empty -- electorates.geojson region.geojson
ELECT_DIV is in electorates.geojson. it is getting set as the ID on all the features, but each one is not getting the proper 2012_POP from the join with the tsv. however, at the top level, electorates and region are getting the last value of 2012_POP from the tsv, so it's joining in some way...
any ideas on what i'm doing wrong? do i need to do this in more than one topo command?
thanks!
UPDATE W REQUESTED INFO
2012_oz_population.tsv
CED_CODE NAME 2011_POP 2012_POP
101 Banks 154938 156527
electorates.geojson
"features": [
{ "type": "Feature", "properties": { "ELECT_DIV": "Lingiari", "STATE": "NT", "NUMCCDS": 335.0, "ACTUAL": 0.0, "PROJECTED": 0.0, "POPULATION": 0.0, "OVER_18": 0.0, "AREA_SQKM": 1352034.05, "SORTNAME": "Lingiari" }, "geometry": { "type": "MultiPolygon",
region.geojson
"features": [
{ "type": "Feature", "properties": { "scalerank": 5, "featurecla": "Admin-0 country", "labelrank": 5.0, "sovereignt": "Australia", "sov_a3": "AU1", "adm0_dif": 1.0, "level": 2.0, "type": "Dependency", "admin": "Ashmore and Cartier Islands", "adm0_a3": "ATC", "geou_dif": 0.0, "geounit": "Ashmore and Cartier Islands", "gu_a3": "ATC", "su_dif": 0.0, "subunit": "Ashmore and Cartier Islands", "su_a3": "ATC", "brk_diff": 0.0, "name": "Ashmore and Cartier Is.", "name_long": "Ashmore and Cartier Islands", "brk_a3": "ATC", "brk_name": "Ashmore and Cartier Is.", "brk_group": null, "abbrev": "A.C.Is.", "postal": "AU", "formal_en": "Territory of Ashmore and Cartier Islands", "formal_fr": null, "note_adm0": "Auz.", "note_brk": null, "name_sort": "Ashmore and Cartier Islands", "name_alt": null, "mapcolor7": 1.0, "mapcolor8": 2.0, "mapcolor9": 2.0, "mapcolor13": 7.0, "pop_est": -99.0, "gdp_md_est": -99.0, "pop_year": -99.0, "lastcensus": -99.0, "gdp_year": -99.0, "economy": "7. Least developed region", "income_grp": "5. Low income", "wikipedia": -99.0, "fips_10": null, "iso_a2": "-99", "iso_a3": "-99", "iso_n3": "036", "un_a3": "-099", "wb_a2": "-99", "wb_a3": "-99", "woe_id": -99.0, "adm0_a3_is": "AUS", "adm0_a3_us": "ATC", "adm0_a3_un": -99.0, "adm0_a3_wb": -99.0, "continent": "Oceania", "region_un": "Oceania", "subregion": "Australia and New Zealand", "region_wb": "East Asia & Pacific", "name_len": 23.0, "long_len": 27.0, "abbrev_len": 7.0, "tiny": -99.0, "homepart": -99.0 }, "geometry": { "type": "Polygon", "coordinates":
now that ive written that out (and figured out how to do basic markdown in Stackoverflow like a clown), i wonder, is it getting caught up on the join of the name in region.geojson?
thx much for the help #mbostock
so embarrassingly (as this has happened before to me), this was because i was using an outdated version of topojson.
after i updated the version to 1.2.3 (using npm update -g topojson) the properties mapped appropriately with the above command.
thx for responding regardless mike. i feared it was something on my end. alas, it was.

Resources