How can I expand array with a category stored in a dictionary?
E.g. for the following input,
{"weigths":
[
{"name":"apple","weigth":200},
{"name":"tomato", "weigth":100}
],
"categories":
[
{"name":"apple","category":"fruit"},
{"name":"tomato","category":"vegetable"}
]
}
I need a performance-efficient way to append respective category to each object in weights, resulting in output:
{"weigths":
[
{"name":"apple","weigth":200, "category": "fruit"},
{"name":"tomato", "weigth":100, "category": "vegetable"}
],
}
Is it something for JOIN/4? (I never tried it)
Update:
Ideally I would like to deal with a not-that-SQL object for categories: full input looking like this
{"weigths":
[
{"name":"apple","weigth":200},
{"name":"orange", "weigth":300}
{"name":"tomato","weigth":100},
{"name":"spinach","weigth":50},
],
"categories":
{
"fruit": ["apple", "orange"],
"vegetable": ["tomato", "spinach"]
}
}
...still getting a similar output:
{"weigths":
[
{"name": "apple", "weigth": 200, "category": "fruit"},
{"name": "orange", "weigth": 300, "category": "fruit"},
{"name": "tomato", "weigth": 100, "category": "vegetable"}
{"name": "spinach", "weigth": 50, "category": "vegetable"}
],
}
Using the SQL-Style Operators JOIN and INDEX would be:
{weights: [JOIN(INDEX(.categories[]; .name); .weigths[]; .name; add)]}
{
"weights": [
{
"name": "apple",
"weigth": 200,
"category": "fruit"
},
{
"name": "tomato",
"weigth": 100,
"category": "vegetable"
}
]
}
Demo
For the updated structure, the INDEX of .categories needs to be tweaked (e.g. employing to_entries) in order to provide the .key as .category for each array item:
{weights: [JOIN(
# INDEX(.categories[]; .name); # This has been replaced with:
INDEX(.categories | to_entries[]; .value[]) | .[] |= {category: .key};
.weigths[]; .name; add)]}
{
"weights": [
{
"name": "apple",
"weigth": 200,
"category": "fruit"
},
{
"name": "orange",
"weigth": 300,
"category": "fruit"
},
{
"name": "tomato",
"weigth": 100,
"category": "vegetable"
},
{
"name": "spinach",
"weigth": 50,
"category": "vegetable"
}
]
}
Demo
You may be interested in checking out ~Q (pronounced "unquery"), a query language that I very recently released, that just like jq can run as a command-line tool.
https://github.com/xcite-db/Unquery
In the first case, the query would be:
{
"#var cat:categories[]": {
"$(name)":"category"
},
"#return:weigths[]": [{
"{}:" : ".",
"category":"$var(cat).$(name)"
}]
}
And in the updated example, the query is:
{
"#var cat: categories:{}:[]": {
"$(.)": "$key"
},
"#return:weigths[]": [{
"{}:": ".",
"category":"$var(cat).$(name)"
}]
}
In either case, the trick is to start by generating a map from fruits to categories, and then use this map to add the category to each entry. So the difference is only in the first part (generating the map).
A variable in ~Q can contain any JSON value/document. The code:
"#var cat: categories:{}:[]": {
"$(.)": "$key"
},
Converts categories in-memory into:
{
"apple": "fruit",
"orange": "fruit",
"spinach": "vegetable",
"tomato": "vegetable"
}
And after that, you can use it to retrieve the category with $var(cat).$(name). If you have a different structure for categories, all you need to do is to change that part of the code to generate the mapping from the categories structure.
Related
From Wikidata, I get the following json:
# Sparql query
query=$(cat ./myquery.sparql)
response=$(curl -G --data-urlencode query="${query}" https://wikidata.org/sparql?format=json)
echo "${response}" | jq '.results.bindings'
[
{
"language": {
"type": "uri",
"value": "https://lingualibre.org/entity/Q100"
},
"wikidata": {
"type": "literal",
"value": "Q36157"
},
"code": {
"type": "literal",
"value": "lub"
}
},
{
"language": {
"type": "uri",
"value": "https://lingualibre.org/entity/Q101"
},
"wikidata": {
"type": "literal",
"value": "Q36284"
},
"code": {
"type": "literal",
"value": "srr"
}
}
]
I would like to have the keys directly paired with their values, such as :
[
{
"language": "https://lingualibre.org/entity/Q100",
"wikidata": "Q36157",
"iso": "lub"
},
{
"language": "https://lingualibre.org/entity/Q101",
"wikidata": "Q36284",
"iso": "srr"
}
]
I currently have a non-resilient code, which will break whenever the key names change :
jq 'map({"language":.language.value,"wikidata":.wikidata.value,"iso":.code.value})'
How to pair the keys with their values in a resilient way (not naming the keys) ?
I want to "prune" the child objects so to only keep the value.
You could use map_values which works like the outer map but for objects, i.e. it retains the object structure, including the field names:
jq 'map(map_values(.value))'
[
{
"language": "https://lingualibre.org/entity/Q100",
"wikidata": "Q36157",
"code": "lub"
},
{
"language": "https://lingualibre.org/entity/Q101",
"wikidata": "Q36284",
"code": "srr"
}
]
Note that this solution lacks the name conversion from code to iso.
Suppose I have a database of movies with some genres tagged to it. My Weaviate schema looks like this:
"classes": [{
"class": "Movie",
"properties": [{
"name": "name",
"dataType": ["string"],
}, {
"name": "inGenres",
"dataType": ["Genre"],
}],
}, {
"class": "Genre",
"properties": [{
"name": "name",
"dataType": ["string"],
}],
}]
I would like to exclude movies tagged with a specific genre from the search results. Specifically, for a database containing the following Movie objects:
{"name":"foo", "inGenres":[{"name":"drama"}]}
{"name":"bar", "inGenres":[{"name":"horror"},{"name":"thriller"}]}
{"name":"baz", "inGenres":[{"name":"horror"},{"name":"sci-fi"}]}
If I exclude the horror genre, the search results should only return the movie foo. Is there any way to perform such a query with GraphQL or the Python client?
You can use the where filter to achieve this.
In your specific case:
{
Get {
Article(
where: {
path: ["inGenres", "Genre", "name"],
operator: NotEqual,
valueString: "horror"
}
) {
name
inGenres {
... on Genre {
name
}
}
}
}
}
In Python
import weaviate
client = weaviate.Client("http://localhost:8080")
where_filter = {
"path": ["inGenres", "Genre", "name"],
"operator": "NotEqual",
"valueString": "horror"
}
query_result = client.query.get("Movie", ["name"]).with_where(where_filter).do()
print(query_result)
I have this below json format, I want to take the list of "id" which satisfies the condition
in this below I want to take the id which has matchers.value as dev-stack and status.state as active
{
"status": "success",
"data": [
{
"id": "b5e7f85d",
"matchers": [
{
"name": "stack",
"value": "dev-stack",
"isRegex": true
}
],
"startsAt": "2020-07-13T07:17:36Z",
"endsAt": "2020-07-15T07:15:44Z",
"updatedAt": "2020-07-13T07:15:59.643692023Z",
"createdBy": "api",
"comment": "Silence",
"status": {
"state": "active"
}
},
{
"id": "1fdaa4b5",
"matchers": [
{
"name": "stack",
"value": "qa-stack",
"isRegex": true
}
],
"startsAt": "2020-07-10T13:19:12Z",
"endsAt": "2020-07-10T13:20:55.510739499Z",
"updatedAt": "2020-07-10T13:20:55.510739499Z",
"createdBy": "api",
"comment": "Silence",
"status": {
"state": "expired"
}
}
]
}
Here is a solution which uses update assignment |=, map and select to update .data.
Note it avoids an undesirable cartesian product if multiple .matchers meet the criteria by using any.
.data |= map(select(
(.matchers | any(.value=="dev-stack")) and (.status.state=="active")
))
Try it online!
I have records like these with sometimes duplicate srcPath entries, though with different references.
For example /content/dam/foo/about-bar/photos/rayDavis.PNG appears 3 times in one record, with different references.
I'd like to get the unique srcPath printed once, and the associated references.
I also have empty records,
{
"pages": []
}
I don't want to see those.
I'd really like a csv with:
srcPath, perhaps a different field like published, and first reference, second reference, third reference, etc. -- associated references array as consecutive comma separated values on the same line, like:
"/content/dam/foo/about-bar/pdf/theplan.pdf", true, "/content/foo/en/about-bar/the-plan-and-vision/jcr:content/content2/image/link", "/content/foo/en/about-bar/the-plan-and-vision/jcr:content/content2/textboximg/boxFtr", "/content/foo/en/about-bar/the-plan-and-vision/jcr:content/content1/textboximg/text"
"/content/dam/foo/about-bar/photos/rayDavis.PNG", true, "/content/foo/en/about-bar/jcr:content/content1B/promos_1/image/fileReference", "/content/foo/en/about-bar/monkey-development/tales-of-giving/ray-moose-davis/jcr:content/content1/textboximg/fileReference", "/content/foo/en/about-bar/monkey-development/tales-of-giving/jcr:content/content1/textboximg_2/fileReference"
"/content/dam/foo/about-bar/pdf/foo_19thNewsletter.pdf", true, "/content/foo/en/gremlins/stay-tuned/jcr:content/content3/textboximg/text"
"/content/dam/foo/about-bar/pdf/barNews_fall1617.pdf", true, "/content/foo/en/gremlins/jcr:content/content2C/textboximg_114671747/text", "/content/dam/foo/about-bar/pdf/barNews_fall1617.pdf", "/content/foo/en/gremlins/stay-tuned/jcr:content/content3/textboximg_0/text"
In other words, unique srcPath entries with associated references.
I imagine if I wanted path too, I wouldn't be able to have unique srcPath lines in the csv?
DATA:
{
"pages": [
{
"srcPath": "/content/dam/foo/about-bar/pdf/theplan.pdf",
"srcTitle": "theplan.pdf",
"path": "/content/foo/en/about-bar/the-plan-and-vision",
"title": "the Plan and Vision",
"references": [
"/content/foo/en/about-bar/the-plan-and-vision/jcr:content/content2/image/link",
"/content/foo/en/about-bar/the-plan-and-vision/jcr:content/content2/textboximg/boxFtr",
"/content/foo/en/about-bar/the-plan-and-vision/jcr:content/content1/textboximg/text"
],
"published": false,
"isPage": "true"
}
]
}
{
"pages": []
}
{
"pages": []
}
{
"pages": [
{
"srcPath": "/content/dam/foo/about-bar/photos/rayDavis.PNG",
"srcTitle": "rayDavis.PNG",
"path": "/content/foo/en/about-bar",
"title": "About bar",
"references": [
"/content/foo/en/about-bar/jcr:content/content1B/promos_1/image/fileReference"
],
"published": true,
"isPage": "true"
},
{
"srcPath": "/content/dam/foo/about-bar/photos/rayDavis.PNG",
"srcTitle": "rayDavis.PNG",
"path": "/content/foo/en/about-bar/monkey-development/tales-of-giving/ray-moose-davis",
"title": "ray moose Davis",
"references": [
"/content/foo/en/about-bar/monkey-development/tales-of-giving/ray-moose-davis/jcr:content/content1/textboximg/fileReference"
],
"published": true,
"isPage": "true"
},
{
"srcPath": "/content/dam/foo/about-bar/photos/rayDavis.PNG",
"srcTitle": "rayDavis.PNG",
"path": "/content/foo/en/about-bar/monkey-development/tales-of-giving",
"title": "tales of Giving",
"references": [
"/content/foo/en/about-bar/monkey-development/tales-of-giving/jcr:content/content1/textboximg_2/fileReference"
],
"published": true,
"isPage": "true"
}
]
}
{
"pages": [
{
"srcPath": "/content/dam/foo/about-bar/pdf/foo_19thNewsletter.pdf",
"srcTitle": "foo_19thNewsletter.pdf",
"path": "/content/foo/en/gremlins/stay-tuned",
"title": "Stay tuned",
"references": [
"/content/foo/en/gremlins/stay-tuned/jcr:content/content3/textboximg/text"
],
"published": true,
"isPage": "true"
}
]
}
{
"pages": [
{
"srcPath": "/content/dam/foo/about-bar/pdf/barNews_fall1617.pdf",
"srcTitle": "barNews_fall1617.pdf",
"path": "/content/foo/en/gremlins",
"title": "gremlins",
"references": [
"/content/foo/en/gremlins/jcr:content/content2C/textboximg_114671747/text"
],
"published": true,
"isPage": "true"
},
{
"srcPath": "/content/dam/foo/about-bar/pdf/barNews_fall1617.pdf",
"srcTitle": "barNews_fall1617.pdf",
"path": "/content/foo/en/gremlins/stay-tuned",
"title": "Stay tuned",
"references": [
"/content/foo/en/gremlins/stay-tuned/jcr:content/content3/textboximg_0/text"
],
"published": true,
"isPage": "true"
}
]
}
You can use the following :
jq --raw-output '.pages | group_by(.srcPath)[] | [.[0].srcPath, .[0].published, .[].references[]] | #csv'
We group the pages by srcPath and map each group into an array that contains the srcPath and published of the first element of the group as well as the references of each element of the group. Each of these arrays will be a row in the CSV result.
Try it here !
I am attempting to create a product with variations in WooCommerce but I am getting this error:
{u'message': u'No route was found matching the URL and request method', u'code': u'rest_no_route', u'data': {u'status': 404}}
when I run the create_variation function from the API.
I ran a GET on the attributes for the product I created and it found no attributes even though the printed response when I created the product had the attributes listed.
Here is my code to create the variable product:
data = {
"name": row[3],
"type": "variable",
"description": row[4],
"images": [
{
"src": row[15],
"position": 0
}
],
"in_stock": True,
"sku": row[2],
'attributes': [
{
'name': 'Size',
'variation': True,
'visible': True,
'options': sizeList,
},
{
'name': 'Color',
'variation': True,
'visible': True,
'options': colorList,
}
],
}
print(wcapiNew.post("products", data).json())
Here is my code to create the variations:
result = wcapi.get("products/sku/"+row[2]).json()
product_id = result['product']['id']
variationData = {
"regular_price": row[17],
"image": {
"src": row[13]
},
"sku": row[19],
"attributes": [
{
"name": "Color",
"option": row[6]
},
{
"name": "Size",
"option": row[10]
}
]
}
print(wcapiNew.post("products/"+str(product_id)+"/variations", variationData).json())
I've been tearing my hair out trying to figure out what I'm doing wrong but I'm clueless right now.
Any help is appreciated. Thanks.
This is my variations data, and it work.
data_1 = {
"regular_price": "9.00",
"sku": "premium-quality-101-red",
"attributes": [
{
"id": 1,
"option": "Red"
}]
}
I figure out that you need to use id, and update one variation at a time.