Update a subdocument list object value in RethinkDB - rethinkdb

{
"id": 1,
"subdocuments": [
{
"id": "A",
"name": 1
},
{
"id": "B",
"name": 2
},
{
"id": "C",
"name": 3
}
]
}
How do update a subdocument "A"s "name" to a value of 2 in RethinkDB in either Javascript or Python?

If you can rely of the position of your "A " element you can update like this:
r.db("DB").table("TABLE").get(1)
.update({subdocuments:
r.row("subdocuments").changeAt(0, r.row("subdocuments").nth(0).merge({"name":2}))})
If you can not rely on the position, you have to find it yourself:
r.db("DB").table("TABLE").get(1).do(function(doc){
return doc("subdocuments").offsetsOf(function(sub){return sub("id").match("A")}).nth(0)
.do(function(index){
return r.db("DB").table("TABLE").update({"subdocuments":
doc("subdocuments").changeAt(index, doc("subdocuments").nth(index).merge({"name":2})) })})
})
As an alternative you can use the map function to iterate over the array elements and update the one that matches your condition
r.db("DB").table("TABLE").get(1)
.update({
subdocuments: r.row("subdocuments").map(function(sub){
return r.branch(sub("id").eq("A"), sub.merge({name: 2}), sub)
})
})

Related

Transform array of values to array of key value pair

I have a json data which is in the form of key and all values in a array but I need to transform it into a array of key value pairs, here is the data
Source data
"2022-08-30T06:58:56.573730Z": [
{ "tag": "AC 3 Phase/7957", "value": 161.37313113545272 },
{ "tag": "AC 3 Phase/7956", "value": 285.46869739695853 }
]
}
Transformation looking for
[
{ "tag": "AC 3 Phase/7957",
"ts": 2022-08-30T06:58:56.573730Z,
"value": 161.37313113545272
},
{ "tag": "AC 3 Phase/7956",
"ts": 2022-08-30T06:58:56.573730Z,
"value": 285.46869739695853
}
]
I would do it like this:
$each($$, function($entries, $ts) {
$entries.{
"tag": tag,
"ts": $ts,
"value": value
}
}) ~> $reduce($append, [])
Feel free to play with this example on the playground: https://stedi.link/g6qJGcP

ReferenceManyFields (One to Many Relationship)

I am working on a project where I have to create one to many relationships which will get all the list of records referenced by id in another table and I have to display all the selected data in the multi-select field (selectArrayInput). Please help me out in this, if you help with an example that would be great.
Thanks in advance.
Example:
district
id name
1 A
2 B
3 C
block
id district_id name
1 1 ABC
2 1 XYZ
3 2 DEF
I am using https://github.com/Steams/ra-data-hasura-graphql hasura-graphql dataprovider for my application.
You're likely looking for "nested object queries" (see: https://hasura.io/docs/1.0/graphql/manual/queries/nested-object-queries.html#nested-object-queries)
An example...
query MyQuery {
district(where: {id: {_eq: 1}}) {
id
name
blocks {
id
name
}
}
}
result:
{
"data": {
"district": [
{
"id": 1,
"name": "A",
"blocks": [
{
"id": 1,
"name": "ABC"
},
{
"id": 2,
"name": "XYZ"
}
]
}
]
}
}
Or...
query MyQuery2 {
block(where: {district: {name: {_eq: "A"}}}) {
id
name
district {
id
name
}
}
}
result:
{
"data": {
"block": [
{
"id": 1,
"name": "ABC",
"district": {
"id": 1,
"name": "A"
}
},
{
"id": 2,
"name": "XYZ",
"district": {
"id": 1,
"name": "A"
}
}
]
}
}
Setting up the tables this way...
blocks:
districts:
Aside: I recommend using plural table names as they are more standard, "districts" and "blocks"

RxJS distinct on array of objects in property

i am having an observable which returns something like this:
"#odata.context": "here is the context URL",
"value": [
{
"Id": 1,
"Value": "A"
},
{
"Id": 2,
"Value": "B"
},
{
"Id": 3,
"Value": "C"
},
{
"Id": 4,
"Value": "A"
}
]
}
Using RxJS i would like to get into the "value" property and use distinct on it to limit the response to something like this:
"#odata.context": "here is the context URL",
"value": [
{
"Id": 1,
"Value": "A"
},
{
"Id": 2,
"Value": "B"
},
{
"Id": 3,
"Value": "C"
}
]
}
could you help me with it?
It pretty much depends on how exactly you want to use this RxJS chain but I hope this leads you the right direction:
const source = of(data)
.pipe(
mergeMap(d => d.value),
distinct(v => v.Value),
toArray(),
)
.subscribe(console.log);
mergeMap will reiterate the array of values as separate emissions where distinct will ignore duplicate Values. Then toArray() will just collect all results.
Live demo: https://stackblitz.com/edit/rxjs-is1zp4

JMESPath current array index

In JMESPath with this query:
people[].{"index":#.index,"name":name, "state":state.name}
On this example data:
{
"people": [
{
"name": "a",
"state": {"name": "up"}
},
{
"name": "b",
"state": {"name": "down"}
},
{
"name": "c",
"state": {"name": "up"}
}
]
}
I get:
[
{
"index": null,
"name": "a",
"state": "up"
},
{
"index": null,
"name": "b",
"state": "down"
},
{
"index": null,
"name": "c",
"state": "up"
}
]
How do I get the index property to actually have the index of the array? I realize that #.index is not the correct syntax but have not been able to find a function that would return the index. Is there a way to include the current array index?
Use-case
Use Jmespath query syntax to extract the numeric index of the current array element, from a series of array elements.
Pitfalls
As of this writing (2019-03-22) this feature is not a part of the standard Jmespath specification.
Workaround
This is possible when running Jmespath from within any of various programming languages, however this must be done outside of Jmespath.
This is not exactly the form you requested but I have a possible answer for you:
people[].{"name":name, "state":state.name} | merge({count: length(#)}, #[*])
this request give this result:
{
"0": {
"name": "a",
"state": "up"
},
"1": {
"name": "b",
"state": "down"
},
"2": {
"name": "c",
"state": "up"
},
"count": 3
}
So each attribute of this object have a index except the last one count it just refer the number of attribute, so if you want to browse the attribute of the object with a loop for example you can do it because you know that the attribute count give the number of attribute to browse.

UnderscoreJs : objects sortBy with empty attributes

Problem is, I want to sort by price an array of users that might contains empty attributes like this one:
var array = [
{
"created": "2015-11-27T16:33:46.781Z",
"name": "Johan",
"pricing": {
"base_price" : "12",
"price_by_hour" : "5"
}
},
{
"created": "2015-11-27T16:33:46.781Z",
"name": "Marco"
},
{
"created": "2015-11-27T16:33:46.781Z",
"name": "Jane",
"pricing": {
"base_price" : "8",
"price_by_hour" : "11"
}
}
];
array = _.sortBy(array, function(item) {
return item.pricing.base_price;
});
console.log(array);
TypeError: Cannot read property 'base_price' of undefined
How can I put the items without the pricing object at the bottom of my list and still sorting it?
In this case, I want to sort the list with Jane first, then Johan, then Marco.
Here's an easy way to do it:
_.sortBy(array, 'pricing.base_price');
When you pass a string as an iteratee to sortBy(), the property() function is used. This function works with property paths and simply returns undefined if the property doesn't exist.
Just put a conditional
array = _.sortBy(array, function(item){
if(item.pricing){
return item.pricing.base_price;
}
});
OK, I just had to return false if the attribute is empty:
array = _.sortBy(array, function(item) {
if(!item.pricing || !item.pricing.base_price){
return -1;
}
return item.pricing.base_price;
});
You need a conditional to avoid getting TypeError. Also you need to cast base_price to Number to get a proper sorting.
array = _.sortBy(array, function(item){
if(item.pricing){
return Number(item.pricing.base_price);
}
});
One alternative would be already initate them as Number.
var array = [
{
"created": "2015-11-27T16:33:46.781Z",
"name": "Johan",
"pricing": {
"base_price" : 12,
"price_by_hour" : 5
}
},
{
"created": "2015-11-27T16:33:46.781Z",
"name": "Marco"
},
{
"created": "2015-11-27T16:33:46.781Z",
"name": "Jane",
"pricing": {
"base_price" : 8,
"price_by_hour" : 11
}
}
];
array = _.sortBy(array, function(item) {
if(item.pricing){
return item.pricing.base_price;
}
});

Resources