Query inside dictionary object with cosmos? - sql

I have a data structure like this:
{
dictionary: {
anotherThing: {
id: "hello";
type: "string"
}
}
}
another document:
{
dictionary: {
a: {
id: "123";
type: "number"
},
random: "cba"
}
}
Is there a query in cosmos I can do that allows me to iterate over the keys in the dictionary object to query inside the nested objects (i.e. where dictionary.x.type = "number")?

1.use UDF. But the performance of UDF is worse and cost can be expensive.
2.change your schema like this:
dictionary: [
{
name:"a",
value:{
id: "123",
type: "number"
}
}
]
Then you can try this sql:
SELECT c FROM c JOIN d IN c.dictionary Where d['value'].type = "number"

Related

Join two collection in mongodb

I'm new in mongodb. Could you please tell me how to perform join operation in this. I've two collection:
Collection 1 ("user")
{
_id: "d04d53dc-fb88-433e-a1c5-dd41a68d7655",
userName: "XYZ User",
age: 12
}
Collection 2 ("square")
{
_id: "ef6f6ac2-a08a-4f68-a63c-0b4a70285427",
userId: "d04d53dc-fb88-433e-a1c5-dd41a68d7655",
side: 4,
area: 16
}
Now I want to retrieve the data from collection 2 is like this.
Expected output:
{
_id: "ef6f6ac2-a08a-4f68-a63c-0b4a70285427",
userId: "d04d53dc-fb88-433e-a1c5-dd41a68d7655",
userName: "XYZ User",
side: 4,
area: 16
}
Thanks in advance :)
Here's one way to do it.
db.square.aggregate([
{
"$lookup": {
"from": "user",
"localField": "userId",
"foreignField": "_id",
"as": "userDoc"
}
},
{
"$set": {
"userName": {
"$first": "$userDoc.userName"
}
}
},
{ "$unset": "userDoc" }
])
Try it on mongoplayground.net.
You can keep the first documentid (_id) in the second document as userId for refrence and after that, you can use the join feature supported by MongoDB 3.2 and later versions. You can use joins by using an aggregate query.
You can do it using the below example :
db.user.aggregate([
// Join with square table
{
$lookup:{
from: "square", // other table name
localField: "_id", // name of user table field
foreignField: "userId", // name of square table field
as: "square" // alias for userinfo table
}
},
{ $unwind:"$user_info" }, // $unwind used for getting data in object or for one record only
// define some conditions here
{
$match:{
$and:[{"userName" : "XYZ User"}]
}
},
// define which fields are you want to fetch
{
$project:{
_id: 1,
userId: "$square.userId",
userName: 1,
side: "$square.side",
area: "$square.area"
}
}
]);
The Result will be
{
_id: "ef6f6ac2-a08a-4f68-a63c-0b4a70285427",
userId: "d04d53dc-fb88-433e-a1c5-dd41a68d7655",
userName: "XYZ User",
side: 4,
area: 16
}
Cheers

Flatten complex json using Databricks and ADF

I have following json which I have flattened partially using explode
{
"result":[
{
"employee":[
{
"employeeType":{
"name":"[empName]",
"displayName":"theName"
},
"groupValue":"value1"
},
{
"employeeType":{
"name":"#bossName#",
"displayName":"theBoss"
},
"groupValue":[
{
"id":"1",
"type":{
"name":"firstBoss",
"displayName":"CEO"
},
"name":"Martha"
},
{
"id":"2",
"type":{
"name":"secondBoss",
"displayName":"cto"
},
"name":"Alex"
}
]
}
]
}
]
}
I need to get following fields:
employeeType.name
groupValue
I am able to extract those fields and value. But, if name value starts with # like in "name":"#bossName#", I am getting groupValue as string from which I need to extract id and name.
"groupValue":[
{
"id":"1",
"type":{
"name":"firstBoss",
"displayName":"CEO"
},
"name":"Martha"
},
{
"id":"2",
"type":{
"name":"secondBoss",
"displayName":"cto"
},
"name":"Alex"
}
]
How to convert this string to json and get the values.
My code so far:
from pyspark.sql.functions import *
db_flat = (df.select(explode("result.employee").alias("emp"))
.withColumn("emp_name", col(emp.employeeType.name))
.withColumn("emp_val",col("emp.groupValue")).drop("emp"))
How can I extract groupValue from db_flat and get id and name from it. Maybe use python panda library.
Since you see they won't be dynamic. You can traverse through the json while mapping like as below. Just identify record and array, specify index [i] as needed.
Example:
id --> $['employee'][1]['groupValue'][0]['id']
name --> $['employee'][1]['groupValue'][0]['type']['name']

GraphQL queries with multiple aliases and Apollo (Vue.js)

I'm trying to fetch data from a single collection type of my Strapi backend into a Vue.js project using Apollo. It works well with a single alias, but I'm having troubles making it work with multiple aliases.
I'm getting my data from a collection type of "campaigns" which has a boolean field of "archive". I want to create an array of "campaigns" that contains all of the campaigns that haven't been archived (archive = false) as well as an array of "archive" that contains all of the archived ones (archive = true).
This is my code:
import gql from "graphql-tag";
export default {
name: "Campaigns",
data() {
return {
campaigns: [],
archive: []
};
},
apollo: {
campaigns: gql`
query getCampaigns {
campaigns: campaigns(where: { archive: "false" }, sort: "order:DESC") {
name
url
}
archive: campaigns(where: { archive: "true" }, sort: "order:DESC") {
name
url
}
}
`
}
The query returns an array of "campaigns", but the array of "archive" is still empty.
I've tried switching things up (put the archive alias first, switched the boolean values to make sure I can generally access the data of the archived campaigns etc.). The problem apparently lies with the "archive"-alias.
When I use the same query with Strapi's GraphQL playground I get the desired result:
{
campaigns: campaigns(where: { archive: "false" }, sort: "order:DESC") {
name
}
archive: campaigns(where: { archive: "true" }, sort: "order:DESC") {
name
}
}
... returns ...
{
"data": {
"campaigns": [
{
"name": "2020"
},
{
"name": "2019"
},
{
"name": "2018"
},
{
"name": "2017"
}
],
"archive": [
{
"name": "2016"
},
{
"name": "2015"
}
]
}
}
How can I make the query work in Vue.js with Apollo?
I think I've found a solution. Technically speaking I guess these are separate queries (which sort of defeats the purpose of aliases if I'm correct) but it does what I want:
apollo: {
campaigns: {
query: gql`
query {
campaigns: campaigns(
where: { archive: "false" }
sort: "order:desc"
) {
name
url
}
}
`
},
archive: {
query: gql`
query {
archive: campaigns(where: { archive: "true" }, sort: "order:desc") {
name
url
}
}
`
}
}
Apparently under some circumstance the initialization "apollo: { XYZ:" and the alias "query { XYZ:" have to match. I've seen in the docs that they don't necessarily have to match, but I don't fully understand when and why.
I guess I can't really tell what the initial parameter does.
You're using campaigns as the key for your entire query, so you need to initialize your data like this:
data() {
return {
campaigns: {
campaigns: [],
archive: [],
},
};
},
Then you can access each list through the key (i.e. campaigns.campaigns and campaigns.archive).
I believe the best way to do this is to use the update property: https://apollo.vuejs.org/guide/apollo/queries.html#name-matching
apollo: {
campaigns: {
query: gql`
query {
campaigns: campaigns(
where: { archive: "false" }
sort: "order:desc"
) {
name
url
}
}
`
},
archive: {
update: data => data.campaigns,
query: gql`
query {
campaigns(where: { archive: "true" }, sort: "order:desc") {
name
url
}
}
`
}
}

Elasticsearch sum aggregration

there is documents with category(number), and piece(long) fields. I need some kind of aggregration that group these docs by category and sum all the pieces in it
here how documents looks:
{
"category":"1",
"piece":"10.000"
},
{
"category":"2",
"piece":"15.000"
} ,
{
"category":"2",
"piece":"10.000"
},
{
"category":"3",
"piece":"5.000"
}
...
The query result must be like:
{
"category":"1",
"total_amount":"10.000"
}
{
"category":"2",
"total_amount":"25.000"
}
{
"category":"3",
"total_amount":"5.000"
}
..
any advice ?
You want to do a terms aggregation on the categories, from the records above I see that you are sending them as strings, so they will be categorical variables. Then, as a metric, pass on the sum.
This is how it might look:
"aggs" : {
"categories" : {
"terms" : {
"field" : "category"
},
"aggs" : {
"sum_category" : {
"sum": { "field": "piece" }
}
}
}
}

How to serialize c# object array into json object without an array

I want to use JsonConvert.Serialize in order to serialize a c# array class object into a json non-array object.
public list<employee> employees;
Output:
"{\"employees\":
{\"name\":\"Alex\",\"number\":\"25860340\"},
{\"name\":\"Tom\",\"number\":\"94085345\"}
}"
The format you have asked for in your question would not be valid JSON, because objects are not allowed to follow one another directly unless they are part of an array (see JSON.org). However, you could transform your employee list into a dictionary and serialize that instead, so long as you had a suitable key to use. One idea would be to use the employee number as a key, for example:
var employees = new List<Employee>
{
new Employee { name = "Alex", number = "25860340" },
new Employee { name = "Tom", number = "94085345" }
};
var obj = new
{
employees = employees.ToDictionary(e => e.number)
};
string json = JsonConvert.SerializeObject(obj, Formatting.Indented);
Console.WriteLine(json);
That would give you this output, which is close to what you wanted:
{
"employees": {
"25860340": {
"name": "Alex",
"number": "25860340"
},
"94085345": {
"name": "Tom",
"number": "94085345"
}
}
}
If the employee number isn't actually unique, you could instead use each employee's position in the list as a key like this:
int i = 0;
var obj = new
{
employees = employees.ToDictionary(e => i++)
};
This would give you the following output instead:
{
"employees": {
"0": {
"name": "Alex",
"number": "25860340"
},
"1": {
"name": "Tom",
"number": "94085345"
}
}
}