Related
I am dealing with the following JSON in a Postgres database column called steps in a table called tCampaign :
[
{
"name":"Step 1",
"stepReference":"01e9f7c0-bc79-11eb-ab6f-2fa1cb676e38",
"rewardConditions": [
{
"conditionDefinitions": [
{
"instanceId":"01805260-0818-4e99-e5b1-5820d1b133cd",
"type":"registration",
"properties": null,
"name": "Registration"
},
{
"instanceId":"01e115c3-5e56-437a-5d13-6c04281e9588",
"type":"optIn",
"properties": null,
"name":"Opt In"
}
],
"rewardDefinitions":[
{
"instanceId":"01c82190-1d56-44f9-474a-513732302e28",
"type":"sportsReward",
"properties": {"activation": {"type": "onReward"}, "betFlavour": "SPORTS", "channels": ["__use_campaign_restrictions__"], "expiry": {"offset": {"days": "02", "hours": "00", "minutes": "00", "seconds": "00"}, "type": "relative"}, "inRunning": "-", "maxReward": {"USD": "1"}, "minimumOdds": "", "oddsInput": {"minimumOdds": {"american": "", "european": ""}}, "retail": "offBetBuild", "returnStakeOnPayout": "false"},
"name":"Freebet",
"calculator":{"type":"fixed","value":"100"}
}
]
}
]
},
{
"name" : "Step 2",
"stepReference" : "01daa4a0-bc79-11eb-ab6f-2fa1cb676e38",
"rewardConditions": [
{
"conditionDefinitions": [
{
"instanceId" : "01fb15ae-01d0-49e1-966a-8ff438e9a191",
"type" : "genericSportsBet",
"properties" : {"betFlavour": "SPORTS", "betTrackEventThreshold": "10", "betTypes": [ "SGL" ], "builderBetOption": "ALL", "channels": [ "__use_campaign_restrictions__" ], "currencyThresholdMap": { "USD": "1" }, "eventHierarchySelection": { "categories": [], "classes": [], "events": [], "marketTemplates": [], "markets": [ "5824" ], "retrobetEventIds": [ "1200" ], "selections": [], "selectionsMarket": [], "types": [] }, "eventHierarchySelectionUI": { "markets": [ { "id": 5824, "mapping": [], "name": "Match Result", "parentId": 1200, "parentParentId": 5, "path": [ "Category: |England|", "Class: |England Premier League|", "Type: |GK Team K| |vs| |GK Team L|" ], "selectionMapper": false, "settled": "N", "startTime": "2021-05-31 11:15:00", "status": "A" } ] }, "inRunning": "-", "legTypes": [ "WIN" ], "metOnSettlement": false, "minOdds": "", "oddsInput": { "minOdds": { "american": "", "european": "" } }, "priceTypes": [ "LP" ]},
"name" : "Sports Bet"
}
],
"rewardDefinitions":[
{
"instanceId" : "0110eb70-44f9-4d57-40bb-09ff4169136c",
"type" : "sportsReward",
"properties" : {"activation": {"type": "onReward"}, "betFlavour": "SPORTS", "channels": ["__use_campaign_restrictions__"], "expiry": {"offset": {"days": "02", "hours": "00", "minutes": "00", "seconds": "00"}, "type": "relative"}, "inRunning": "-", "maxReward": {"USD": "2"}, "minimumOdds": "", "oddsInput": {"minimumOdds": {"american": "", "european": ""}}, "retail": "offBetBuild", "returnStakeOnPayout": "false"},
"name" : "Freebet",
"calculator" : {"type":"fixed","value":"100"}
}
]
}
]
}
]
and have written the following query to extract properties from conditionDefinitions :
select conditionDefinitions->'properties' as properties from tcampaign cmp
LEFT JOIN LATERAL json_array_elements(steps) singleStep ON true
LEFT JOIN LATERAL json_array_elements(singleStep->'rewardConditions') rewardConditions on TRUE
LEFT JOIN LATERAL json_array_elements(rewardConditions->'conditionDefinitions') conditionDefinitions on TRUE
where properties is not null ;
but I get the following error :
ERROR: column "properties" does not exist
LINE 5: where properties is null ;
If I remove the where clause the query runs fine. Why do I not have access to properties in the where clause? Because I can see results coming back if I remove the WHERE clause, so the query does have results
I am indexing all the file names into the index. But when I search with exact file name in the search query it is returning all other file names also. below is my index definition.
{
"fields": [
{
"name": "id",
"type": "Edm.String",
"facetable": true,
"filterable": true,
"key": true,
"retrievable": true,
"searchable": false,
"sortable": false,
"analyzer": null,
"indexAnalyzer": null,
"searchAnalyzer": null,
"synonymMaps": [],
"fields": []
},
{
"name": "FileName",
"type": "Edm.String",
"facetable": false,
"filterable": false,
"key": false,
"retrievable": true,
"searchable": true,
"sortable": false,
"analyzer": "keyword-analyzer",
"indexAnalyzer": null,
"searchAnalyzer": null,
"synonymMaps": [],
"fields": []
}
],
"scoringProfiles": [],
"defaultScoringProfile": null,
"corsOptions": null,
"analyzers": [
{
"name": "keyword-analyzer",
"#odata.type": "#Microsoft.Azure.Search.CustomAnalyzer",
"charFilters": [],
"tokenizer": "keyword_v2",
"tokenFilters": ["lowercase", "my_asciifolding", "my_word_delimiter"]
}
],
"tokenFilters": [
{
"#odata.type": "#Microsoft.Azure.Search.AsciiFoldingTokenFilter",
"name": "my_asciifolding",
"preserveOriginal": true
},
{
"#odata.type": "#Microsoft.Azure.Search.WordDelimiterTokenFilter",
"name": "my_word_delimiter",
"generateWordParts": true,
"generateNumberParts": false,
"catenateWords": false,
"catenateNumbers": false,
"catenateAll": false,
"splitOnCaseChange": true,
"preserveOriginal": true,
"splitOnNumerics": true,
"stemEnglishPossessive": false,
"protectedWords": []
}
],
"#odata.etag": "\"0x8D6FB2F498F9AD2\""
}
Below is my sample data
{
"value": [
{
"id": "1",
"FileName": "SamplePSDFile_1psd2680.psd"
},
{
"id": "2",
"FileName": "SamplePSDFile-1psd260.psd"
},
{
"id": "3",
"FileName": "SamplePSDFile_1psd2689.psd"
},
{
"id": "4",
"FileName": "SamplePSDFile-1psdxx2680.psd"
}
]
}
Below is the Analyze API results
{
"tokens": [
{
"token": "samplepsdfile_1psd2689.psd",
"startOffset": 0,
"endOffset": 26,
"position": 0
},
{
"token": "samplepsdfile",
"startOffset": 0,
"endOffset": 13,
"position": 0
},
{
"token": "psd",
"startOffset": 15,
"endOffset": 18,
"position": 1
},
{
"token": "psd",
"startOffset": 23,
"endOffset": 26,
"position": 2
}
]
}
When I search with the keyword "SamplePSDFile_1psd2689.psd", Azure search returning three records in the results instead of only document 3. Below is my search query and the results.
?search="SamplePSDFile_1psd2689.psd"&api-version=2019-05-06&$count=true&queryType=full&searchMode=All
{
"#odata.count": 3,
"value": [
{
"#search.score": 2.3387241,
"id": "2",
"FileName": "SamplePSDFile-1psd260.psd"
},
{
"#search.score": 2.2493405,
"id": "3",
"FileName": "SamplePSDFile_1psd2689.psd"
},
{
"#search.score": 2.2493405,
"id": "1",
"FileName": "SamplePSDFile_1psd2680.psd"
}
]
}
How I can achieve my expected results. I tried with and without double quotes around the keyword all other options, but no luck. What I am doing wrong here in this case?
Some body suggested to use $filter, but that field wasn't filterable in our case.
Please help me on this.
If you are looking for exact match then you probably don't want any analyzer involved. Give it a try with this line
"analyzer": "keyword-analyzer"
changed to
"analyzer": null
If you need to be able to do exact match on the field and also support partial keyword searches then you need to index the field twice with different names. Maybe append “Exact” to the exact match field name and don’t use an analyzer for that one. The name without exact can have an analyzer. Then search on the field using the right field name index depending on the type of search.
I have a author bucket. And in this bucket I keep the author infos and author's articles. I want to select the articles that have the tags I want from the author bucket.
I have tried this but I could not find how to do the filtering.
SELECT art.* FROM author AS a
UNNEST a.articles AS art
WHERE art.tags = 'History'
This is author bucket:
{
"about": {
"name": "sassa",
"userName": "sassatur"
},
"articles": [
{
"authorId": [
"8c7ba33e-0674-4d99-bfad-29d144028bc9"
],
"claps": [],
"comments": [],
"content": {
"articleType": "HTML",
"data": "My First Article"
},
"id": "71d6fa22-61be-4a93-8e86-8d569080da97",
"publishStatus": "UNLISTED",
"statistic": {
"articleId": "71d6fa22-61be-4a93-8e86-8d569080da97",
"views": [
1602683127039,
1602683148270
]
},
"tags": [
"Art, History"
],
"title": "Culture"
},
{
"authorId": [
"8c7ba33e-0674-4d99-bfad-29d144028bc9"
],
"claps": [],
"comments": [],
"content": {
"articleType": "HTML",
"data": "My First Article"
},
"id": "81d6fa22-63be-4a93-8e86-8d569080da97",
"publishStatus": "UNLISTED",
"statistic": {
"views": [
1602683127039,
1602683148270
]
},
"tags": [
"Art"
],
"title": "Culture"
}
],
"id": "8c7ba33e-0674-4d99-bfad-29d144028bc9",
}
Try using ANY/IN/SATISFIES, like so:
SELECT art.* FROM author AS a
UNNEST a.articles AS art
WHERE ANY x IN art.tags SATISFIES x == 'Art' END;
This works for 'Art' in your example, but not 'History' because of the way you are storing tags. It's an array, but it appears to have a single(?) item with comma-separated values. So, instead of "tags": ["Art,History"], I would recommend: "tags": ["Art","History"] instead, and then it will work.
However, if you are stuck with the comma-separate string, you can use SPLIT and ARRAY_CONTAINS as well:
SELECT art.* FROM author AS a
UNNEST a.articles AS art
WHERE ANY x IN art.tags SATISFIES ARRAY_CONTAINS(SPLIT(x,", "), 'History') END;
All of the following is being performed in eBay's API sandbox.
I am attempting to list an item by using the inventory API. Specifically, I have created an inventory item and a relevant offer for that item. When I make a POST request to the publish offer endpoint, I get the following error:
{
"errors": [
{
"errorId": 25016,
"domain": "API_INVENTORY",
"subdomain": "Selling",
"category": "REQUEST",
"message": "The title value is invalid. Seller Provided Title Value is missing."
},
{
"errorId": 25002,
"domain": "API_INVENTORY",
"subdomain": "Selling",
"category": "REQUEST",
"message": "A user error has occurred. The duration \"GTC\" day(s) is not available for this listing type, or invalid for category \"49996\".",
"parameters": [
{
"name": "0",
"value": "GTC"
},
{
"name": "1",
"value": "49996"
}
]
}
]
}
I can't see any reference in any of the API documentation to a "Seller Provided Title". The duration error is also confusing as the API says it only supports "GTC" listings. The product has a title so it must be in reference to something else.
My inventory item is as follows:
{
"sku": "13725",
"product": {
"title": "Harley Davidson bike",
"aspects": {
"Year": [
"2016"
],
"Model": [
"Road Glide Special"
],
"Manufacurer": [
"Harley-Davidson®"
],
"Type": [
"Touring"
],
"For Sale By": [
"Dealer"
],
"Vehicle Title": [
"Clear"
],
"Mileage": [
"13393"
],
"VIN (Vehicle Identification Number)": [
"1HD1KTM10GB627264"
],
"Color": [
"Black Quartz"
]
},
"description": "Item description goes here",
"imageUrls": [
"https://dw4i9za0jmiyk.cloudfront.net/2018/01/12/pre_ic60e5df584b870c3d2a55c86800eede_70618b24eb08.jpg"
]
},
"condition": "USED_EXCELLENT",
"availability": {
"pickupAtLocationAvailability": [
{
"quantity": 1,
"merchantLocationKey": "425",
"availabilityType": "IN_STOCK",
"fulfillmentTime": {
"value": 1,
"unit": "DAY"
}
}
]
}
}
And my offer object is as follows:
{
"offerId": "5852159010",
"sku": "13725",
"marketplaceId": "EBAY_MOTORS",
"format": "FIXED_PRICE",
"availableQuantity": 0,
"pricingSummary": {
"price": {
"value": "18294.0",
"currency": "USD"
}
},
"listingPolicies": {
"paymentPolicyId": "5807565000",
"fulfillmentPolicyId": "5806186000"
},
"categoryId": "49996",
"merchantLocationKey": "425",
"tax": {
"applyTax": false
},
"status": "UNPUBLISHED",
"eBayPlusEligible": false
}
I had similar issues on sandbox, and came to the conculsion it was broken.
They also have some limits on only certain categories working.
Have you tried it agains the live API, I have found this to be far more reliable, ignoring the fact doing development work live is dangerous!
For your info here is my working code offer:
inventory_template = {
"availability": {
"shipToLocationAvailability": {
"quantity": product.quantity_available
}
},
"condition": "NEW",
"product": {
"aspects": {spec.name: [spec.value] for spec in product.specifics},
"brand": product.product_brand,
"description": product.product_description,
"imageUrls": [
"https://ebay.mydomain.co.uk/{}".format(img.image_link) for img in product.images],
"mpn": product.product_mpn,
"title": product.product_title,
"upc": [
product.product_upc,
],
"ean": [
product.product_ean,
],
# "epid": "string"
},
"sku": sku,
}
offer_body = {
"availableQuantity": offer.available_quantity,
"categoryId": offer.category_id,
"listingDescription": html,
"listingPolicies": {
"paymentPolicyId": offer.payment_policy_id,
"returnPolicyId": offer.return_policy_id,
"fulfillmentPolicyId": offer.fulfillment_policy_id,
},
"merchantLocationKey": offer.merchant_location_key,
"pricingSummary": {
"price": {
"value": offer.summary_price_value,
"currency": offer.summary_price_currency
}
},
"sku": offer.sku,
"marketplaceId": offer.marketplace_id,
"format": offer.format
}
the offer.available_quantity etc are items from my database, its the structure I'm showing.
I'm new in lodash (v3.10.1), and having a hard time understanding.
Hope someone can help.
I have an input something like this:
{
{"id":1,"name":"Matthew","company":{"id":1,"name":"abc","industry":{"id":5,"name":"Medical"}}},
{"id":2,"name":"Mark","company":{"id":1,"name":"abc","industry":{"id":5,"name":"Medical"}}},
{"id":3,"name":"Luke","company":{"id":1,"name":"abc","industry":{"id":5,"name":"Medical"}}},
{"id":4,"name":"John","company":{"id":1,"name":"abc","industry":{"id":5,"name":"Medical"}}},
{"id":5,"name":"Paul","company":{"id":1,"name":"abc","industry":{"id":5,"name":"Medical"}}}
];
I would like to output this or close to this:
{
"industries": [
{
"industry":{
"id":5,
"name":"Medical",
"companies": [
{
"company":{
"id":1,
"name":"abc",
"employees": [
{"id":1,"name":"Matthew"},
{"id":2,"name":"Mark"},
{"id":3,"name":"Luke"},
{"id":4,"name":"John"},
{"id":5,"name":"Paul"}
]
}
}
]
}
}
]
}
Here's something that gets you close to what you want. I structured the output to be an object instead of an array. You don't need the industries or industry properties in your example output. The output structure looks like this:
{
"industry name": {
"id": "id of industry",
"companies": [
{
"company name": "name of company",
"id": "id of company",
"employees": [
{
"id": "id of company",
"name": "name of employee"
}
]
}
]
}
}
I use the _.chain function to wrap the collection with a lodash wrapper object. This enables me to explicitly chain lodash functions.
From there, I use the _.groupBy function to group elements of the collection by their industry name. Since I'm chaining, I don't have to pass in the array again to the function. It's implicitly passed via the lodash wrapper. The second argument of the _.groupBy is the path to the value I want to group elements by. In this case, it's the path to the industry name: company.industry.name. _.groupBy returns an object with each employee grouped by their industry (industries are keys for this object).
I then do use _.transform to transform each industry object. _.transform is essentially _.reduce except that the results returned from the _.transform function is always an object.
The function passed to the _.transform function gets executed against each key/value pair in the object. In the function, I use _.groupBy again to group employees by company. Based off the results of _.groupBy, I map the values to the final structure I want for each employee object.
I then call the _.value function because I want to unwrap the output collection from the lodash wrapper object.
I hope this made sense. If it doesn't, I highly recommend reading Lo-Dash Essentials. After reading the book, I finally got why lodash is so useful.
"use strict";
var _ = require('lodash');
var emps = [
{ "id": 1, "name": "Matthew", "company": { "id": 1, "name": "abc", "industry": { "id": 5, "name": "Medical" } } },
{ "id": 2, "name": "Mark", "company": { "id": 1, "name": "abc", "industry": { "id": 5, "name": "Medical" } } },
{ "id": 3, "name": "Luke", "company": { "id": 1, "name": "abc", "industry": { "id": 5, "name": "Medical" } } },
{ "id": 4, "name": "John", "company": { "id": 1, "name": "abc", "industry": { "id": 5, "name": "Medical" } } },
{ "id": 5, "name": "Paul", "company": { "id": 1, "name": "abc", "industry": { "id": 5, "name": "Medical" } } }
];
var result = _.chain(emps)
.groupBy("company.industry.name")
.transform(function(result, employees, industry) {
result[industry] = {};
result[industry].id = _.get(employees[0], "company.industry.id");
result[ industry ][ 'companies' ] = _.map(_.groupBy(employees, "company.name"), function( employees, company ) {
return {
company: company,
id: _.get(employees[ 0 ], 'company.id'),
employees: _.map(employees, _.partialRight(_.pick, [ 'id', 'name' ]))
};
});
return result;
})
.value();
Results from your example are as follows:
{
"Medical": {
"id": 5,
"companies": [
{
"company": "abc",
"id": 1,
"employees": [
{
"id": 1,
"name": "Matthew"
},
{
"id": 2,
"name": "Mark"
},
{
"id": 3,
"name": "Luke"
},
{
"id": 4,
"name": "John"
},
{
"id": 5,
"name": "Paul"
}
]
}
]
}
}
If you ever wanted the exact same structure as in the questions, I solved it using the jsonata library:
(
/* lets flatten it out for ease of accessing the properties*/
$step1 := $ ~> | $ |
{
"employee_id": id,
"employee_name": name,
"company_id": company.id,
"company_name": company.name,
"industry_id": company.industry.id,
"industry_name": company.industry.name
},
["company", "id", "name"] |;
/* now the magic begins*/
$step2 := {
"industries":
[($step1{
"industry" & $string(industry_id): ${
"id": $distinct(industry_id)#$I,
"name": $distinct(industry_name),
"companies": [({
"company" & $string(company_id): {
"id": $distinct(company_id),
"name": $distinct(company_name),
"employees": [$.{
"id": $distinct(employee_id),
"name": $distinct(employee_name)
}]
}
} ~> $each(function($v){ {"company": $v} }))]
}
} ~> $each(function($v){ {"industry": $v} }))]
};
)
You can see it in action on the live demo site: https://try.jsonata.org/VvW4uTRz_