Vega Chloropleth Map Visualisation - maps

For some reason vega is reading my data as 0 when the numbers range from 1-234.
I am attempting to show a visualisation of a chloropleth map of crypto-ownership by country.
The countries have been ranked 1-234 and that is meant to show on the tooltip however, this is being shown as 0 on the tooltip. How do I fix this.
Here is my code:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"title":{
"text": "Crypto Ownership Worldwide",
"subtitle": "Source: FILL",
"anchor": "start"
},
"width":500,
"height":400,
"data": {
"url": "https://raw.githubusercontent.com/tomiwav/tomiwav.github.io/main/custom.geo%20(3).json",
"format":{"property": "features"}
},
"projection":{"type": "mercator"},
"transform": [
{
"lookup":"properties.name",
"from":{
"key": "Country",
"fields": ["Rank"],
"data":{
"url": "https://raw.githubusercontent.com/tomiwav/tomiwav.github.io/main/datarank.csv",
"format":{"type":"csv"}
}
}
}
],
"mark":{
"type": "geoshape",
"fill":"lightgray",
"stroke":"black",
"strokeWidth":0.5
},
"encoding": {
"color": {
"field": "Rank",
"type": "quantitative",
"scale": {
"domain":[234,1],
"scheme": "oranges"
}
},
"tooltip":[
{"field":"properties.name", "title":"Country"},
{"field":"Rank","type":"quantitative","title":"Number of Crypto Owners","format":".2f"}
]
},
"config": {"mark": {"invalid": null}
}
}

Your lookup was failing. You need a lower case "c" on country.
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"title": {
"text": "Crypto Ownership Worldwide",
"subtitle": "Source: FILL",
"anchor": "start"
},
"width": 500,
"height": 400,
"data": {
"url": "https://raw.githubusercontent.com/tomiwav/tomiwav.github.io/main/custom.geo%20(3).json",
"format": {"property": "features"}
},
"projection": {"type": "mercator"},
"transform": [
{
"lookup": "properties.name",
"from": {
"key": "country",
"fields": ["Rank"],
"data": {
"url": "https://raw.githubusercontent.com/tomiwav/tomiwav.github.io/main/datarank.csv",
"format": {"type": "csv"}
} }
}
],
"mark": {
"type": "geoshape",
"fill": "lightgray",
"stroke": "black",
"strokeWidth": 0.5
},
"encoding": {
"color": {
"field": "Rank",
"type": "quantitative",
"scale": {"domain": [234, 1], "scheme": "oranges"}
},
"tooltip": [
{"field": "properties.name", "title": "Country"},
{
"field": "Rank",
"type": "quantitative",
"title": "Number of Crypto Owners",
"format": ".2f"
}
]
},
"config": {"mark": {"invalid": null}}
}

Related

What is the correct way to integrate audio & visual response using Alexa APL?

I have an Alexa audio and visual response that is returned on the first launch of an Alexa App. I use a transformer to embed the APLA document. Up until recently this was working.
This is the APL document:
{
"type": "APL",
"version": "2022.1",
"license": "Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: LicenseRef-.amazon.com.-AmznSL-1.0\nLicensed under the Amazon Software License http://aws.amazon.com/asl/",
"theme": "dark",
"import": [
{
"name": "alexa-layouts",
"version": "1.5.0"
}
],
"onMount": [
{
"type": "SpeakItem",
"componentId": "initialAPLAcomponent"
}
],
"resources": [
{
"description": "Default resource definitions for Video template",
"dimensions": {
"videoHeight": "55%",
"videoPaddingTop": "80dp",
"videoWidth": "70vw",
"videoControlPaddingBottom": "0dp",
"videoSliderPaddingBottom": "80dp"
}
},
{
"when": "${#viewportProfile == #hubLandscapeLarge}",
"dimensions": {
"videoHeight": "60%",
"videoPaddingTop": "110dp",
"videoControlPaddingBottom": "10dp",
"videoSliderPaddingBottom": "90dp"
}
},
{
"when": "${#viewportProfile == #hubLandscapeSmall || #viewportProfile == #hubRoundSmall}",
"dimensions": {
"videoHeight": "50%",
"videoPaddingTop": "70dp",
"videoControlPaddingBottom": "15dp"
}
}
],
"commands": {
"ToggleVideoOverlay": {
"parameters": [
"componentId",
"show"
],
"commands": [
{
"type": "Sequential",
"commands": [
{
"when": "${show}",
"type": "SetValue",
"componentId": "${componentId}",
"property": "display",
"value": "normal"
},
{
"type": "AnimateItem",
"easing": "ease-in-out",
"duration": 1000,
"componentId": "${componentId}",
"value": [
{
"property": "opacity",
"from": "${show ? 0 : 0.5}",
"to": "${show ? 0.5 : 0}"
}
]
},
{
"when": "${!show}",
"type": "SetValue",
"componentId": "${componentId}",
"property": "display",
"value": "none"
}
]
}
]
},
"ToggleVideoControls": {
"parameters": [
"componentId",
"direction",
"show"
],
"commands": [
{
"type": "Sequential",
"commands": [
{
"type": "AnimateItem",
"easing": "ease-in-out",
"duration": 1000,
"componentId": "${componentId}",
"value": [
{
"property": "opacity",
"from": "${show ? 0 : 1}",
"to": "${show ? 1 : 0}"
},
{
"property": "transform",
"from": [
{
"translateY": "${!show ? 0 : (direction == 'down' ? -50 : 50)}"
}
],
"to": [
{
"translateY": "${show ? 0 : (direction == 'down' ? 50 : -50)}"
}
]
}
]
},
{
"type": "SetValue",
"property": "videoControlsDisplay",
"value": "${show ? true : false}"
}
]
}
]
}
},
"layouts": {
"VideoPlayer": {
"parameters": [
{
"name": "backgroundImageSource",
"description": "URL for the background image source in fullscreen.",
"type": "string"
},
{
"name": "displayFullscreen",
"description": "Select to display video in fullscreen. Video controls will be displayed on tap.",
"type": "boolean",
"default": false
},
{
"name": "headerTitle",
"description": "Title text to render in the header.",
"type": "string"
},
{
"name": "headerSubtitle",
"description": "Subtitle Text to render in the header.",
"type": "string"
},
{
"name": "headerAttributionImage",
"description": "URL for attribution image or logo source (PNG/vector).",
"type": "string"
},
{
"name": "videoControlType",
"description": "The type of video control to use. Default is skip (foward and backwards).",
"type": "string",
"default": "skip"
},
{
"name": "videoSources",
"description": "Video single source or an array of sources. Videos will be in a playlist if multiple sources are provided.",
"type": "any"
},
{
"name": "sliderType",
"description": "Determinate for full control of the slider with transport control. Indeterminate is an ambient progress bar with animation.",
"type": "string",
"default": "determinate"
},
{
"name": "autoplay",
"type": "boolean",
"default": true,
"description": "Determines the starting state of the play/pause icon. This should match the autoplay state of the media playing component. Defaults to false. "
}
],
"item": {
"type": "Container",
"height": "100vh",
"width": "100vw",
"bind": [
{
"name": "sliderThumbPosition",
"type": "number",
"value": 0
},
{
"name": "sliderActive",
"type": "boolean",
"value": false
},
{
"name": "videoProgressValue",
"type": "number",
"value": 0
},
{
"name": "videoTotalValue",
"type": "number",
"value": 0
},
{
"name": "videoControlsDisplay",
"type": "boolean",
"value": false
}
],
"handleTick": [
{
"when": "${!sliderActive && displayFullscreen && videoControlsDisplay}",
"minimumDelay": 5000,
"description": "For video fullscreen view, hide video controls after 5 seconds of inactivity",
"commands": [
{
"type": "Parallel",
"sequencer": "ToggleVideoControlsSequencer",
"commands": [
{
"type": "ToggleVideoOverlay",
"componentId": "videoOverlay",
"show": false
},
{
"type": "ToggleVideoControls",
"componentId": "videoHeader",
"direction": "up",
"show": false
},
{
"type": "ToggleVideoControls",
"componentId": "videoControls",
"direction": "down",
"show": false
}
]
}
]
}
],
"items": [
{
"type": "AlexaBackground",
"id": "AlexaBackground",
"backgroundColor": "${backgroundColor}",
"backgroundImageSource": "${backgroundImageSource}"
},
{
"description": "Video container",
"type": "Container",
"height": "100%",
"width": "100%",
"position": "absolute",
"item": {
"type": "TouchWrapper",
"height": "100%",
"width": "100%",
"description": "Outer touch wrapper that brings up the controls",
"onPress": [
{
"when": "${displayFullscreen}",
"type": "Parallel",
"sequencer": "ToggleVideoControlsSequencer",
"commands": [
{
"type": "ToggleVideoOverlay",
"componentId": "videoOverlay",
"show": true
},
{
"type": "ToggleVideoControls",
"componentId": "videoHeader",
"direction": "down",
"show": true
},
{
"type": "ToggleVideoControls",
"componentId": "videoControls",
"direction": "up",
"show": true
}
]
}
],
"item": {
"type": "Container",
"height": "100%",
"width": "100%",
"alignItems": "center",
"item": {
"type": "Video",
"height": "${displayFullscreen ? '100%' : #videoHeight}",
"width": "${displayFullscreen ? '100%' : #videoWidth}",
"scale": "best-fill",
"autoplay": true,
"audioTrack": "foreground",
"id": "videoPlayerId",
"source": "${videoSources}",
"position": "absolute",
"top": "${displayFullscreen ? '0' : #videoPaddingTop}",
"onPlay": [
{
"type": "SetValue",
"property": "videoTotalValue",
"value": "${event.duration}"
},
{
"type": "SpeakItem",
"componentId": "initialAPLAcomponent"
}
],
"onTrackUpdate": [
{
"type": "SetValue",
"property": "videoTotalValue",
"value": "${event.duration}"
}
],
"onTimeUpdate": [
{
"type": "SetValue",
"property": "videoProgressValue",
"value": "${event.currentTime}"
},
{
"type": "SetValue",
"componentId": "slider",
"property": "progressValue",
"value": "${videoProgressValue}"
},
{
"type": "SetValue",
"property": "videoTotalValue",
"value": "${event.duration}"
}
],
"onTrackReady": [
{
"type": "SetValue",
"property": "videoTotalValue",
"value": "${event.duration}"
}
],
"onTrackFail": [
{
"type": "SetValue",
"property": "videoTotalValue",
"value": "0"
}
]
}
}
}
},
{
"description": "Header, slider, and controls container",
"type": "Container",
"height": "100%",
"width": "100%",
"items": [
{
"description": "Oveylay background for Video Controls",
"when": "${displayFullscreen}",
"type": "Frame",
"id": "videoOverlay",
"height": "100%",
"width": "100%",
"backgroundColor": "${viewport.theme == 'light' ? '#colorWhite' : '#colorBlack'}",
"position": "absolute",
"display": "none",
"opacity": 0
},
{
"when": "${#viewportProfileCategory != #hubRound}",
"type": "AlexaHeader",
"id": "videoHeader",
"opacity": "${displayFullscreen ? 0 : 1}",
"layoutDirection": "${environment.layoutDirection}",
"headerAttributionImage": "${headerAttributionImage}",
"headerTitle": "${headerTitle} ",
"headerSubtitle": "${headerSubtitle} ",
"headerAttributionPrimacy": true,
"width": "100%",
"theme": "${viewport.theme}"
},
{
"description": "Slider and controls",
"type": "Container",
"id": "videoControls",
"opacity": "${displayFullscreen ? 0 : 1}",
"width": "100%",
"position": "absolute",
"bottom": 0,
"items": [
{
"when": "${sliderType != 'indeterminate'}",
"type": "Container",
"alignItems": "center",
"item": [
{
"type": "AlexaSlider",
"id": "slider",
"progressValue": "${videoProgressValue}",
"totalValue": "${videoTotalValue}",
"positionPropertyName": "sliderThumbPosition",
"metadataDisplayed": true,
"metadataPosition": "above_right",
"width": "${#videoWidth + 5vw}",
"paddingBottom": "#videoSliderPaddingBottom",
"theme": "${viewport.theme}",
"onUpCommand": [
{
"type": "ControlMedia",
"componentId": "videoPlayerId",
"command": "seek",
"value": "${sliderThumbPosition - videoProgressValue}"
},
{
"delay": "1000",
"type": "SetValue",
"sequencer": "ToggleVideoControlsSequencer",
"property": "sliderActive",
"value": false
}
],
"onMoveCommand": [
{
"type": "SetValue",
"property": "sliderActive",
"value": true
}
],
"onDownCommand": [
{
"type": "SetValue",
"property": "sliderActive",
"value": true
}
]
},
{
"type": "AlexaTransportControls",
"mediaComponentId": "videoPlayerId",
"playPauseToggleButtonId": "playPauseToggleButtonId",
"primaryControlSize": "70dp",
"secondaryControls": "${videoControlType}",
"secondaryControlSize": "60dp",
"autoplay": true,
"position": "absolute",
"bottom": "#videoControlPaddingBottom",
"theme": "${viewport.theme}"
}
]
},
{
"when": "${sliderType == 'indeterminate'}",
"type": "Container",
"alignItems": "center",
"item": [
{
"type": "AlexaProgressBar",
"progressBarType": "indeterminate",
"width": "#videoWidth",
"paddingBottom": "#videoSliderPaddingBottom",
"theme": "${viewport.theme}"
}
]
}
]
}
]
}
]
}
},
"AudioTransform": {
"parameters": [
{
"name": "audioSource",
"type": "string"
}
],
"items": [
{
"type": "Container",
"items": [
{
"type": "Text",
"id": "initialAPLAcomponent",
"speech": "${audioSource}"
}
]
}
]
}
},
"mainTemplate": {
"parameters": [
"payload"
],
"items": [
{
"type": "VideoPlayer",
"backgroundImageSource": "${payload.videoPlayerTemplateData.properties.backgroundImage}",
"displayFullscreen": "${payload.videoPlayerTemplateData.properties.displayFullscreen}",
"headerAttributionImage": "${payload.videoPlayerTemplateData.properties.logoUrl}",
"headerTitle": "${payload.videoPlayerTemplateData.properties.headerTitle}",
"headerSubtitle": "${payload.videoPlayerTemplateData.properties.headerSubtitle}",
"videoControlType": "${payload.videoPlayerTemplateData.properties.videoControlType}",
"videoSources": "${payload.videoPlayerTemplateData.properties.videoSources}",
"sliderType": "${payload.videoPlayerTemplateData.properties.sliderType}"
},
{
"type": "AudioTransform",
"audioSource": "${payload.videoPlayerTemplateData.properties.outputAPLA.url}"
}
]
}
}
This is the datasource:
{
"videoPlayerTemplateData": {
"type": "object",
"properties": {
"backgroundImage": "",
"displayFullscreen": true,
"headerTitle": "",
"headerSubtitle": "",
"logoUrl": "https://my.png",
"videoControlType": "jump10",
"videoSources": [
"https://my.mp4"
],
"sliderType": "determinate"
},
"transformers": [
{
"template": "intialAPLA",
"outputName": "outputAPLA",
"transformer": "aplAudioToSpeech"
}
]
}
}
and this is the APLA source:
{
"intialAPLA": {
"type": "APLA",
"version": "0.91",
"mainTemplate": {
"parameters": [
"payload"
],
"item": [
{
"type": "Mixer",
"items": [
{
"type": "Sequencer",
"items": [
{
"type": "Audio",
"description": "sound from bank",
"source": "my.sound"
},
{
"type": "Speech",
"content": "myspeech "
}
]
},
{
"type": "Audio",
"source": "https://my.mp3",
"duration": "trimToParent",
"filter": [
{
"type": "Volume",
"amount": "50%"
},
{
"type": "FadeOut",
"duration": 2000
}
]
}
]
}
]
}
}
}
If I remove the video item from the main template the audio plays, so I know this is not an issue with the transformer. I've tried setting the speech attrbute of the video, in layouts, to be the transformer binding, and playing that onMount, but that doesn't work either.
It seems I can only play video or the audio, not both. This worked previously so I'm not sure what's changed.
Are you able to see why I can't return the video with the audio embedded?

Pan and Zoom Tree in Vega

Looking to be able to Pan and Zoom a tree diagram in Vega.
I have the example code working for my data but there is too much of it to be able to reasonably display in even a large chart. Therefore I am looking for a way to pan and zoom.
I have searched Google and SO, but there are zero posts about panning and zooming a tree.
Code used:
"$schema": "https://vega.github.io/schema/vega/v5.json",
"data": [
{
"name": "default",
"transform": [{
"type": "nest",
"generate": true,
"keys": ["$dimension1"]
},
{
"type": "tree",
"method": "tidy",
"size": [{"signal": "height"}, {"signal": "width - 20"}],
"separation": true,
"as": ["y", "x", "depth", "children"]
}
]
},
{
"name": "links",
"source": "default",
"transform": [
{ "type": "treelinks" },
{
"type": "linkpath",
"orient": "horizontal",
"shape": "diagonal"
}
]
}
],
"scales": [
{
"name": "color",
"type": "ordinal",
"domain": {"data": "default", "field": "depth"},
"range": {"scheme": "datastudio20"}
}
],
"marks": [
{
"type": "path",
"from": {"data": "links"},
"encode": {
"update": {
"path": {"field": "path"},
"stroke": {"value": "#ccc"}
}
}
},
{
"type": "symbol",
"from": {"data": "default"},
"encode": {
"enter": {
"size": {"value": 100},
"stroke": {"value": "#fff"}
},
"update": {
"x": {"field": "x"},
"y": {"field": "y"},
"fill": {"scale": "color", "field": "depth"}
}
}
},
{
"type": "text",
"from": {"data": "default"},
"encode": {
"enter": {
"text": {"signal":"datum.$dimension0 || datum.key || 'Customer'"},
"fontSize": {"value": 12},
"baseline": {"value": "middle"}
},
"update": {
"x": {"field": "x"},
"y": {"field": "y"},
"dx": {"signal": "datum.children ? -7 : 7"},
"align": {"signal": "datum.children ? 'right' : 'left'"},
"opacity": 1
}
}
}
]
}```
Here is an example for you:
Editor
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "An example of Cartesian layouts for a node-link diagram of hierarchical data.",
"width": 600,
"height": 600,
"padding": 5,
"autosize": {"type": "none", "resize": false},
"signals": [
{
"name": "hover",
"on": [
{"events": "*:mouseover", "encode": "hover"},
{"events": "*:mouseout", "encode": "leave"},
{"events": "*:mousedown", "encode": "select"},
{"events": "*:mouseup", "encode": "release"}
]
},
{"name": "xrange", "update": "[0, width]"},
{"name": "yrange", "update": "[height, 0]"},
{
"name": "down",
"value": null,
"on": [{"events": "mousedown", "update": "xy()"}]
},
{
"name": "xcur",
"value": null,
"on": [{"events": "mousedown", "update": "slice(xdom)"}]
},
{
"name": "ycur",
"value": null,
"on": [{"events": "mousedown", "update": "slice(ydom)"}]
},
{
"name": "delta",
"value": [0, 0],
"on": [
{
"events": [
{
"source": "window",
"type": "mousemove",
"consume": true,
"between": [
{"type": "mousedown"},
{"source": "window", "type": "mouseup"}
]
}
],
"update": "down ? [down[0]-x(), y()-down[1]] : [0,0]"
}
]
},
{
"name": "anchor",
"value": [0, 0],
"on": [
{
"events": "wheel",
"update": "[invert('xscale', x()), invert('yscale', y())]"
}
]
},
{
"name": "zoom",
"value": 1,
"on": [
{
"events": "wheel!",
"force": true,
"update": "pow(1.001, event.deltaY * pow(16, event.deltaMode))"
}
]
},
{
"name": "xdom",
"update": "slice(xext)",
"on": [
{
"events": {"signal": "delta"},
"update": "[xcur[0] + span(xcur) * delta[0] / width, xcur[1] + span(xcur) * delta[0] / width]"
},
{
"events": {"signal": "zoom"},
"update": "[anchor[0] + (xdom[0] - anchor[0]) * zoom, anchor[0] + (xdom[1] - anchor[0]) * zoom]"
}
]
},
{
"name": "ydom",
"update": "slice(yext)",
"on": [
{
"events": {"signal": "delta"},
"update": "[ycur[0] + span(ycur) * delta[1] / height, ycur[1] + span(ycur) * delta[1] / height]"
},
{
"events": {"signal": "zoom"},
"update": "[anchor[1] + (ydom[0] - anchor[1]) * zoom, anchor[1] + (ydom[1] - anchor[1]) * zoom]"
}
]
},
{"name": "size", "update": "clamp(20 / span(xdom), 1, 1000)"}
],
"data": [
{
"name": "tree",
"url": "data/flare.json",
"transform": [
{"type": "stratify", "key": "id", "parentKey": "parent"},
{
"type": "tree",
"method": {"signal": "'tidy'"},
"size": [{"signal": "height"}, {"signal": "width+100"}],
"separation": {"signal": "true"},
"as": ["y", "x", "depth", "children"]
},
{"type": "extent", "field": "x", "signal": "xext"},
{"type": "extent", "field": "y", "signal": "yext"}
]
},
{
"name": "links",
"source": "tree",
"transform": [
{"type": "treelinks", "signal": "upstream"},
{
"type": "linkpath",
"orient": "horizontal",
"shape": {"signal": "'diagonal'"},
"sourceY": {"expr": "scale('yscale', datum.source.y)"},
"sourceX": {"expr": "scale('xscale', datum.source.x)"},
"targetY": {"expr": "scale('yscale', datum.target.y)"},
"targetX": {"expr": "scale('xscale', datum.target.x)"}
}
]
}
],
"scales": [
{
"name": "color",
"type": "linear",
"range": {"scheme": "magma"},
"domain": {"data": "tree", "field": "depth"},
"zero": true
},
{
"name": "xscale",
"zero": false,
"domain": {"signal": "xdom"},
"range": {"signal": "xrange"}
},
{
"name": "yscale",
"zero": false,
"domain": {"signal": "ydom"},
"range": {"signal": "yrange"}
}
],
"marks": [
{
"type": "path",
"from": {"data": "links"},
"encode": {
"update": {"path": {"field": "path"}, "stroke": {"value": "#ccc"}}
}
},
{
"type": "symbol",
"from": {"data": "tree"},
"clip": true,
"encode": {
"enter": {"size": {"value": 100}, "stroke": {"value": "#fff"}},
"update": {
"x": {"scale": "xscale", "field": "x"},
"y": {"scale": "yscale", "field": "y"},
"fill": {"scale": "color", "field": "depth"}
}
}
},
{
"type": "text",
"from": {"data": "tree"},
"clip": true,
"encode": {
"enter": {
"text": {"field": "name"},
"fontSize": {"value": 9},
"baseline": {"value": "middle"}
},
"update": {
"x": {"scale": "xscale", "field": "x"},
"y": {"scale": "yscale", "field": "y"},
"dx": {"signal": "datum.children ? -7 : 7"},
"align": {"signal": "datum.children ? 'right' : 'left'"},
"opacity": {"signal": "1"}
}
}
}
]
}

react-jsonschema-form conditional field

I've got this form with react-jsonschema-form
{
"type": "object",
"required": ["startDate", "endDate"],
"properties": {
"endDate": {
"type": "string",
"title": "Do",
"format": "date"
},
"startDate": {
"type": "string",
"title": "Od",
"format": "date"
},
"allDay": {
"type": "boolean",
"title": "All day",
"default": true
}
}
}
And I want to change the format of the fields based on the checkbox, something like this:
{
"type": "object",
"required": ["startDate", "endDate"],
"properties": {
"endDate": {
"type": "string",
"title": "Do",
"format": "date"
},
"startDate": {
"type": "string",
"title": "Od",
"format": "date"
},
"allDay": {
"type": "boolean",
"title": "All day",
"default": true
}
},
"allOf": [
{
"if": {
"properties": {
"allDay": false
}
},
"then": {
"properties": {
"endDate": {
"format": "date-time"
},
"startDate": {
"format": "date-time"
}
},
"required": ["startDate", "endDate"]
}
}
]
}
But it doesn't seem to work. I know that it can be done via a selectbox, but I want to use the checkbox.
Are there any possibilities to this problem?

Elastic - JSON Array nested in Array

I have to index a json to Elastic which look like the below format. My problem is that the key "variable" is array that contains json objects (I thought about "nested" datatype of Elastic) but some of those objects it's possible to contain nested json arrays inside them. (see variable CUSTOMERS).
POST /example_data/data {
"process_name": "TEST_PROCESS",
"process_version ": 0,
"process_id": "1111",
"activity_id": "111",
"name": "update_data",
"username": "testUser",
"datetime": "2018-01-01 10:00:00",
"variables": [{
"name": "ΒΑΝΚ",
"data_type": "STRING",
"value": "EUROBANK"
},{
"name": "CITY",
"data_type": "STRING",
"value": "LONDON"
}, {
"name": "CUSTOMERS",
"data_type": "ENTITY",
"value": [{
"variables": [{
"name": "CUSTOMER_NAME",
"data_type": "STRING",
"value": "JOHN"
}, {
"name": " CUSTOMER_CITY",
"data_type": "STRING",
"value": "LONDON"
}
]
}
]
}, {
"name": "CUSTOMERS",
"data_type": "ENTITY",
"value": [{
"variables": [{
"name": "CUSTOMER_NAME",
"data_type": "STRING",
"value": "ΑΘΗΝΑ"
}, {
"name": " CUSTOMER_CITY ",
"data_type": "STRING",
"value": "LIVERPOOL"
}, {
"name": " CUSTOMER_NUMBER",
"data_type": "STRING",
"value": "1234567890"
}
]
}
]
}
] }
When I'm trying to index it I get the following error
{ "error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "Can't merge a non object mapping [variables.value] with an object mapping [variables.value]"
}
],
"type": "illegal_argument_exception",
"reason": "Can't merge a non object mapping [variables.value] with an object mapping [variables.value]" }, "status": 400 }
Mapping
{ "example_data": {
"mappings": {
"data": {
"properties": {
"activity_id": {
"type": "text"
},
"name": {
"type": "text"
},
"process_name": {
"type": "text"
},
"process_version": {
"type": "integer"
}
"process_id": {
"type": "text"
},
"datetime": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"username": {
"type": "text",
"analyzer": "greek"
},
"variables": {
"type": "nested",
"properties": {
"data_type": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"value": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
}}}
When I remove the variable CUSTOMERS that contains the array, then It works properly because there are only json objects.
Is there a way to handle that? Thanks in advance

How to score by max relevance match in array elements in ElasticSearch?

I have an autocomplete analyser for a field("keywords"). This field is an array of strings. When I query with a search string I want to show first the documents where a single element of the array keywords matches best. The problem is that if a part of the string matches with more elements of the array "keywords", then this document appears before another that has less but better matches. For example, if I have a query with the word "gas station" the returning documents' keywords are these:
"hits": [
{
"_index": "locali_v3",
"_type": "categories",
"_id": "5810767ddc536a03b4761acd",
"_score": 3.1974547,
"_source": {
"keywords": [
"Radio Station",
"Radio Station"
]
}
},
{
"_index": "locali_v3",
"_type": "categories",
"_id": "581076d8dc536a03b4761cc3",
"_score": 3.0407648,
"_source": {
"keywords": [
"Stationery Store",
"Stationery Store"
]
}
},
{
"_index": "locali_v3",
"_type": "categories",
"_id": "5810767ddc536a03b4761ace",
"_score": 2.903595,
"_source": {
"keywords": [
"TV Station",
"TV Station"
]
}
},
{
"_index": "locali_v3",
"_type": "categories",
"_id": "581076cddc536a03b4761c87",
"_score": 2.517158,
"_source": {
"keywords": [
"Praktoreio Ugrwn Kausimwn/Gkaraz",
"Praktoreio Ygrwn Kaysimwn/Gkaraz",
"Praktoreio Ugron Kausimon/Gkaraz",
"Praktoreio Ygron Kaysimon/Gkaraz",
"Πρακτορείο Υγρών Καυσίμων/Γκαράζ",
"Gas Station"
]
}
}
The "Gas Station" is fourth, although it has the best single element matching. Is there a way to tell ElasticSearch that I do not care about how many times "gas" or "station" appears in keywords? I want the max element of the array keywords match as the score factor.
My settings are:
{
"locali": {
"settings": {
"index": {
"creation_date": "1480937810266",
"analysis": {
"filter": {
"autocomplete_filter": {
"type": "edge_ngram",
"min_gram": "1",
"max_gram": "20"
}
},
"analyzer": {
"keywords": {
"filter": [
"lowercase",
"autocomplete_filter"
],
"char_filter": [
"my_char_filter"
],
"type": "custom",
"tokenizer": "standard"
}
},
"char_filter": {
"my_char_filter": {
"type": "mapping",
"mappings": [
"ί => ι",
"Ί => Ι",
"ή => η",
"Ή => Η",
"ύ => υ",
"Ύ => Υ",
"ά => α",
"Ά => Α",
"έ => ε",
"Έ => Ε",
"ό => ο",
"Ό => Ο",
"ώ => ω",
"Ώ => Ω",
"ϊ => ι",
"ϋ => υ",
"ΐ => ι",
"ΰ => υ"
]
}
}
},
"number_of_shards": "1",
"number_of_replicas": "1",
"uuid": "TJjOt9L9QE2HrsUFHM6zJg",
"version": {
"created": "2040099"
}
}
}
}
}
And the mappings:
{
"locali": {
"mappings": {
"places": {
"properties": {
"formattedCategories": {
"properties": {
"english": {
"type": "string"
},
"greek": {
"type": "string"
}
}
},
"keywords": {
"type": "string",
"analyzer": "keywords"
},
"loc": {
"properties": {
"coordinates": {
"type": "geo_point"
}
}
},
"location": {
"properties": {
"formattedAddress": {
"properties": {
"english": {
"type": "string"
},
"greek": {
"type": "string"
}
}
},
"locality": {
"properties": {
"english": {
"type": "string"
},
"greek": {
"type": "string"
}
}
},
"neighbourhood": {
"properties": {
"english": {
"type": "string"
},
"greek": {
"type": "string"
}
}
}
}
},
"name": {
"properties": {
"english": {
"type": "string"
},
"greek": {
"type": "string"
}
}
},
"rating": {
"properties": {
"rating": {
"type": "long"
}
}
},
"seenDetails": {
"type": "long"
},
"verified": {
"type": "long"
}
}
},
"regions": {
"properties": {
"keywords": {
"type": "string",
"analyzer": "keywords"
},
"loc": {
"properties": {
"coordinates": {
"type": "geo_point"
}
}
},
"name": {
"properties": {
"english": {
"type": "string"
},
"greek": {
"type": "string"
}
}
},
"type": {
"type": "long"
},
"weight": {
"type": "long"
}
}
},
"categories": {
"properties": {
"keywords": {
"type": "string",
"analyzer": "keywords"
},
"name": {
"properties": {
"english": {
"type": "string"
},
"greek": {
"type": "string"
}
}
},
"weight": {
"type": "long"
}
}
}
}
}
}
Can you post your query here that you are trying here as well.
I tried your example with the following query
{
"query": {"match": {
"keywords": "gas station"
}
}
}
And i got your desired result.
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 3,
"max_score": 0.081366636,
"hits": [
{
"_index": "stack",
"_type": "type",
"_id": "AVjP6QnpdNp-z_ybGd-L",
"_score": 0.081366636,
"_source": {
"keywords": [
"Praktoreio Ugrwn Kausimwn/Gkaraz",
"Praktoreio Ygrwn Kaysimwn/Gkaraz",
"Praktoreio Ugron Kausimon/Gkaraz",
"Praktoreio Ygron Kaysimon/Gkaraz",
"Πρακτορείο Υγρών Καυσίμων/Γκαράζ",
"Gas Station"
]
}
},
{
"_index": "stack",
"_type": "type",
"_id": "AVjP5-u5dNp-z_ybGd-I",
"_score": 0.03182549,
"_source": {
"keywords": [
"Radio Station",
"Radio Station"
]
}
},
{
"_index": "stack",
"_type": "type",
"_id": "AVjP6KiKdNp-z_ybGd-K",
"_score": 0.03182549,
"_source": {
"keywords": [
"TV Station",
"TV Station"
]
}
}
]
}
}
Try this query to see if you are getting desired result. Also you can reply with your mappings, query and ES version if this does't work for you.
Hope this solves your problem. Thanks

Resources