SwiftUI - Create static array from dictionary - swift

I am trying to create an array with keys from a dictionary based on certain values from it. The dictionary that I have is employees_main.json and looks something like this:
{
"John Doe": {
"role": "Engineer",
"location": "Europe",
"isEmployedFullTime": true
},
"Jane Doe": {
"role": "Manager",
"location": "Europe",
"isEmployedFullTime": true
},
"U.N. Owen": {
"role": "Tech",
"location": "Europe",
"isEmployedFullTime": false
}
}
To load it into Swift I have create a Struct in a file called Employee.swift, as well as a Bundle-Decodable.swift file, and it loaded correctly.
struct Employee: Codable {
let role: String
let location: String
let isEmployedFullTime: Bool
}
Now in my ContentView I am trying to import the dictionary into an array of keys. My current code looks so:
struct ContentView: View {
#State private var employees = Bundle.main.decode("employees_main.json")
var employees_names: [String] {
employess.map(\.key)
}
}
This works in creating an array of the keys, but the array is shuffled every time it is called, breaking code further down which assumes a static structure, e.g. employees_names[1] will always be "Jane Doe". The second thing is I want to only get the keys where isEmployedFullTime is set to true, however I am not sure on how that if statement would look like in this.

Related

Go-MongoDriver decoding JSON array weirdly

Heyho party people,
I've recently took up learning Go and started working on a small side project which includes a API written using the Go Fiber library.
All the necessery data is stored in MongoDB with the following schema
{
"ObjectId": {
"name": "name",
"url": "url",
"dateAdded": "date",
"data": [{
"timestamp 1": "price 1"
},
{
"timestamp 2": "price 2"
}
]
}
}
The item type looks like this:
type Item struct {
ID primitive.ObjectID `json:"_id" bson:"_id"`
Name string `json:"name" bson:"name"`
URL string `json:"url" bson:"url"`
DateAdded string `json:"dateAdded" bson:"dateAdded"`
Data []interface{} `json:"data" bson:"data"`
}
Whenever I query a stored item with
err = collection.FindOne(context.TODO(), filter).Decode(&item)
each map inside of the data-array is wrapped in another array =>
{ test url 2021-04-16 [[{2021-04-16 99.99}] [{2021-04-17 109.99}]] }
instead of
{ test url 2021-04-16 [{2021-04-16 99.99}, {2021-04-17 109.99}] }
Does anybody have an idea on how to fix this?
Thanks in advance!
OK, I've found a way to fix this behaviour for my use case.
As mentioned above, the MongoDB-driver for Go wraps each entry of an array into another respective array, which leads to a nested array.
After trying around for some time I found out, that inserting the document into your collection like the following example,
db.collection.insertOne({ name: "Name", url: "URL", dateAdded: "2021-04-25", data: { "2021-04-25": 9.99, "2021-04-26": 19.99 } })
then the result of a query performed in your program looks like this:
{ ObjectID("60858245f8805dc57a716500") Name URL 2021-04-25 [{ 2021-04-25 9.99 } { 2021-04-26 19.99 }] }
This means, that the JSON-schema should look like this
{
"ObjectId": {
"name": "name",
"url": "url",
"dateAdded": "date",
"data": {
"2021-04-25": 9.99,
"2021-04-26": 19.99
}
}
}
Sadly, I was not able to find out what is actually causing this odd behaviour, but I hope this helps anybody encountering this (or a similar) problem.
EDIT
Changing the type of the Data-field to []bson.M, as mkopriva said in the comments below, fixed it.
type Item struct {
ID primitive.ObjectID `json:"_id" bson:"_id"`
Name string `json:"name" bson:"name"`
URL string `json:"url" bson:"url"`
DateAdded string `json:"dateAdded" bson:"dateAdded"`
Data []bson.M `json:"data" bson:"data"`
}
This way the original JSON-schema does not have to be adapted to the workaround.
{
"ObjectId":{
"name":"name",
"url":"url",
"dateAdded":"date",
"data": [
{
"2021-04-25": 9.99
},
{
"2021-04-26": 19.99
}
]
}
}

How to get rid of an additional key added while inserting a nested struct in mongodb

Suppose this is my struct definition,
type partialContent struct {
key string `json:"key" bson"key"`
value string `json:"value" bson:"value"`
}
type content struct {
id string `json:"id" bson:"_id,omitempty"`
partialContent
}
While storing the content in MongoDB, it gets stored as
{
"_id": ObjectID,
"partialcontent": {
"key": "...",
"value": "..."
}
}
But the JSON unmarshal returns
{
"_id": ObjectID,
"key": "...",
"value": "..."
}
How do I get rid of the additional key partialcontent in MongoDB?
First, you need to export struct fields else the drivers will skip those fields.
If you don't want an embedded document in MongoDB, use the ,inline bson tag option:
type PartialContent struct {
Key string `json:"key" bson"key"`
Value string `json:"value" bson:"value"`
}
type Content struct {
ID string `json:"id" bson:"_id,omitempty"`
PartialContent `bson:",inline"`
}
Inserting this value:
v := Content{
ID: "abc",
PartialContent: PartialContent{
Key: "k1",
Value: "v1",
},
}
Will result in this document in MongoDB:
{ "_id" : "abc", "key" : "k1", "value" : "v1" }

Redshift JSONPaths file for dynamic json file

Given the below json object
{
"player": {
"francesco totti": {
"position": "forward"
},
"andrea pirlo": {
"position": "midfielder"
}
}
}
I would like to import the above file into Redshift as the below rows
name, position
"franceso totti", "forward"
"andrea pirlo", "midfielder"
The thing is the 'player' object has a dynamic number of objects each hour(cadence of when I import into Redshift). For example, the next hour run may look like the following.
{
"player": {
"fabio cannavaro": {
"position": "defender"
}
}
}
Is it possible to use a JSONPaths file to import this file every hour or does it require preprocessing?
You can reuse the jsonpath file as much as you like. You will just need to rerun the COPY statement but remember this will add rows to the table - not replace them. If you are replacing then you will want to clear the table out first (delete, drop/recreate, truncate - each with its own performance and limitations).
Now your json format isn't going to work for Redshift AFAIK. You have the player name as the field identifier and want to set this as the value of a column. You will want something like this (sorry these aren't tested):
{
"player": {
"name": "francesco totti",
"position": "forward"
}
},
{
"player": {
"name": "andrea pirlo",
"position": "midfielder"
}
}
And a jsonpath like this:
{
"jsonpaths": [
"$.player.name",
"$.player.position"
]
}

How to query a reference in MongoDB

I have found this tutorial online which is helpful. However it shows an example using an array of two objectIds. How could the query be done if it was one objectId instead of two?
http://www.tutorialspoint.com/mongodb/mongodb_relationships.htm
{
"_id":ObjectId("52ffc33cd85242f436000001"),
"contact": "987654321",
"dob": "01-01-1991",
"name": "Tom Benzamin",
"address_ids": [
ObjectId("52ffc4a5d85242602e000000"), // if this was not an array and just one ObjectId
ObjectId("52ffc4a5d85242602e000001")
]
}
var result = db.users.findOne({"name":"Tom Benzamin"},{"address_ids":1})
var addresses = db.address.find({"_id":{"$in":result["address_ids"]}})
I hope I got it right. So you have elements of this sort:
{
"_id":ObjectId("52ffc33cd85242f436000001"),
...
"address_ids": ObjectId("52ffc4a5d85242602e000000")
}
Your code will look like this:
var result = db.users.findOne({"name":"Tom Benzamin"},{"address_ids":1})
var addresses = db.address.find({"_id": result["address_ids"]})

MongoDB: How to update a complex item of an array with a new complex item

Here below is once again my hypothetical Users collection where more than one address is allowed:
{
"firstName": "Joe",
"lastName": "Grey",
...
"addresses":
[
{
"name": "Default",
"street": "...",
...,
"isDefault": true
},
{
"name": "Home",
"street": "...",
...,
"isDefault": false
},
{
"name": "Office",
"street": "...",
...,
"isDefault": false
}
]
}
Let's suppose I want to update the second address (Home) with the following new item:
{
"name": "New home",
"street": "Ruta del Sol"
},
How do I update the second item of the array with the new item, also considering that the new item might or might not provide all the fields of an address?
In this post Will shown me how to update a field at a given index, ensuring the address name remains unique. Now, instead of updating a single field, I want to update an entire item.
All you need to do is transform new json data for update . Example:
Let us assume you have new Json data with only two fields 'name' and 'isDefault' .
var newData = {"name" : "New Val","isDefault":true};
var updateData = {};
for (key in newData ) {
updateData["addresses.$."+key]=newData[key];
};
db.projectPlan.update({_id:1, 'addresses.name': 'Home'}, {$set:updateData});
var renamed = 'Office'; // from user input
var users = getUserMongoCollection();
var address = {
name: "Office,
street: "Ruta del Sol"
};
users.update({_id:userId },
{ $set : { 'addresses.1' : address } }, function(err){
//all done!
});