JSON structure for a ticket reservation system with Firebase? - json

I'm currently developing a ticket reservation system where the user should be able to choose an event, see a list of sections, a section contains a list of seats, thats either free or occupied/booked by another user. I've chosen to use Firebase as my backend, but got very little experience with databases and zero using JSON. How would I go about structuring a system like this?
This is what I got so far:
{
"events" : {
"e2017" : {
"name" : "event 2017",
"date" : "1490567256550"
}
},
"eventSections" : {
"e2017" : {
"e2017-A" : {
"isFull" : false,
"totalSeats": 40,
"bookedSeats": 20
}
}
},
"sectionSeats" : {
"e2017-A" : {
"A1": {
"isBooked" : true,
"bookedBy" : "userId"
},
"A2": {
"isBooked" : false,
"bookedBy" : false
}
}
}
}

The following structure is an example structure for a very specific use case of your question. You had the following criteria:
1) user should be able to choose an event
2) see a list of sections
3) a section contains a list of seats
4) (seats are) either free or occupied/booked by another user
and a structure that meets that criteria
events
event_0
sections
section_0
seats
seat_0: "free"
seat_1: "occupied"
section_1
seats
seat_0: "occupied"
seat_1: "occupied"
event_1
sections
section_0
seats
seat_0: "free"
seat_1: "occupied"
section_1
seats
seat_0: "occupied"
seat_1: "occupied"
While this is an answer, it's not the only one. For example. What if you wanted to know which events had free seats? You really can't query this structure for that data (unless you filter in code).
However, if you present a list of events to a user where they can click on the event to get more data, this structure would work fine as it could be used to present sections and seats available.
If you have a different specific use case, update your question with more data.

Related

Bind JSON to build a dynamic form in AngularJs for One-To-Many relationship and having parent-child relations in both the tables

I have two database tables with a one-to-many relationship between them and the parent-child relationship within each of the tables. Here reference table (one side) works as a master table and the reference_copies table (many side) works as replicas of the master.
I want to create UI form in AngularJS to provide insert/update functionalities to the user. As shown in UI_image, user can go up to the n number of level as he/she wants. Also attached the image with database tables structure.
In reference_copies table, data can already exist as we are uploading through excels too. Here, name & type_id columns combining together create unique constraints. So while the user tries to add a level, I need to check if the name exists for that type or not. If exists then fetch the object else save and fetch the saved object (with created id). Here value and selected type will be the same for all levels so the user needs to select only once.
On the final submit, the master form's each level will be mapped with corresponding reference copies' each level. i.e. parent name of a master will be mapped with parent names of reference_copies 1, 2... Likewise, level1 of a master will be mapped with level1 of reference_copies 1& 2. and so on. If there is no corresponding level in either of the form, nothing happens, that level will not be mapped with any. Here, there are no restrictions to create similarity in levels. As shown in the example, the master form is having two levels, reference copy 1 form is having only one level and reference copy 2 form is having 3 levels.
On final Submit button, I want to build the json payload as below: Also when I get the response json in below format with IDs, the form should be filled as shown in above for the update.
{
"name": "Reference Name",
"childs": [
{
"name": "child level1 name",
"childs": [
{
"name": "childlevel2 name",
"childs":[],
"referenceCopies": [
{
"id" : 2004
}
]
}
],
"referenceCopies": [
{
"id": 2001
},
{
"id": 2003
}
]
}
],
"referenceCopies": [
{
"id": 2000
},
{
"id": 2002
}
]
}
I tried with recursive template in AngularJS to achieve this but it's not working. Can anyone provide some demo or suggestion to achieve above kind of requirement.
Please let me know if the above description is incomplete or unclear.

MongoDB queries return no results

I'm having a problem with querying a MongoDB dataset ("On Street Crime in Camden" from data.gov.uk)
The database name is Crime_Data_in_Camden and the collection name is Street_Crime_Camden. The query to find all records, db.Street_Crime_Camden.find(), works fine but anything else returns nothing at
all. Here is a portion of the metadata:
{
"id" : 509935,
"name" : "Ward Name",
"dataTypeName" : "text",
"fieldName" : "ward_name",
"position" : 13,
"renderTypeName" : "text",
"tableColumnId" : 258836,
"width" : 100,
"cachedContents" : {
"largest" : "West Hampstead",
"non_null" : 79813,
"null" : 0,
"top" : [ {
"item" : "Regent's Park",
"count" : 20
}, {
"item" : "Swiss Cottage",
"count" : 19
}, {
"item" : "Holborn and Covent Garden",
"count" : 18
}
}
}
I've tried 3 attempts at a basic query:
db.Street_Crime_Camden.find({"ward_name":"West Hampstead"});
db.Street_Crime_Camden.find({'meta.ward_name':'West Hampstead'});
db.Street_Crime_Camden.find({meta:{ward_name:"West Hampstead"} });
According to any documentation or tutorial that I've seen any of these approaches should be valid. And I know that there are hundreds of rows (or documents) that match those terms, so why are these queries returning nothing? Advice would be appreciated.
The common theme in the three aproaches you tried is some form of ward_name = West Hampstead but there is no attribute named ward_name in the document you shared with us.
Based on the document you show in your question the only way of addressing an attribute with the value West Hampstead is:
db.Street_Crime_Camden.find({"cachedContents.largest": "West Hampstead"});
For background; you address attributes in your documents by using dot notation so the document you included in your question could be found by any of the following find commands:
db.Street_Crime_Camden.find({"name": "Ward Name"});
db.Street_Crime_Camden.find({"position": 13});
db.Street_Crime_Camden.find({"cachedContents.top.item": "Swiss Cottage"});
db.Street_Crime_Camden.find({"cachedContents.top.1.count": 20});
... etc
These examples might help you to understand how to form find criteria. The MongoDB docs are also useful.

BSON document size exceeds 16 MB in mongo document

I would like to store ticket details in an array in a mongo document. it works fine till the document size reaches 16MB, after that I get the exception (Resulting document after update is larger than 16777216) and program terminates abruptly. I cannot split this document coz it stores all the ticket details falls under that year 2016.
here goes my document structure.
{
year:2016,
purpose: ticketdetail,
tickets:[
{ticketid:001, desc:"xyz", created:20161231},
{ticketid:002, desc:"xyz", created:20161231},
{ticketid:003, desc:"xyz", created:20161231},
.......
.......
{ticketid:00N, desc:"xyz", created:20161231},
}]
}
You will need to split your document into separate documents, perhaps in a different collection. I would not recommend GridFS, because you cannot query data within a GridFS blob.
Here is a suggested document structure:
{
_id: ObjectId("85bf0ef0b9692c0010978359"),
"ticketid" : "001",
"desc" : "xyz",
"created" : ISODate("2016-12-31T00:00:00.000Z")
}
,
{
_id: ObjectId("85bed4257726f90010d4e21f"),
"ticketid" : "002",
"desc" : "xyz",
"created" : ISODate("2016-12-31T00:00:00.000Z")
}
Notes on this structure:
Each ticket is in a different document - this makes it scalable, because there is no limit on the number of documents in a collection.
The "created" field is now in a proper date field. This gives you more accurate queryability.
You said that your original document was needed to store all tickets for 2016. A suitable query on this new collection will return you all tickets for 2016, so you don't need to store them all in a single document:
db.tickets.find({
"created" : {
$gte: ISODate("2016-01-01"),
$lt: ISODate("2017-01-01")
}
}
});

How to enter multiple table data in mongoDB using json

I am trying to learn mongodb. Suppose there are two tables and they are related. For example like this -
1st table has
First name- Fred, last name- Zhang, age- 20, id- s1234
2nd table has
id- s1234, course- COSC2406, semester- 1
id- s1234, course- COSC1127, semester- 1
id- s1234, course- COSC2110, semester- 1
how to insert data in the mongo db? I wrote it like this, not sure is it correct or not -
db.users.insert({
given_name: 'Fred',
family_name: 'Zhang',
Age: 20,
student_number: 's1234',
Course: ['COSC2406', 'COSC1127', 'COSC2110'],
Semester: 1
});
Thank you in advance
This would be a assuming that what you want to model has the "student_number" and the "Semester" as what is basically a unique identifier for the entries. But there would be a way to do this without accumulating the array contents in code.
You can make use of the upsert functionality in the .update() method, with the help of of few other operators in the statement.
I am going to assume you are going this inside a loop of sorts, so everything on the right side values is actually a variable:
db.users.update(
{
"student_number": student_number,
"Semester": semester
},
{
"$setOnInsert": {
"given_name": given_name,
"family_name": family_name,
"Age": age
},
"$addToSet": { "courses": course }
},
{ "upsert": true }
)
What this does in an "upsert" operation is first looks for a document that may exist in your collection that matches the query criteria given. In this case a "student_number" with the current "Semester" value.
When that match is found, the document is merely "updated". So what is being done here is using the $addToSet operator in order to "update" only unique values into the "courses" array element. This would seem to make sense to have unique courses but if that is not your case then of course you can simply use the $push operator instead. So that is the operation you want to happen every time, whether the document was "matched" or not.
In the case where no "matching" document is found, a new document will then be inserted into the collection. This is where the $setOnInsert operator comes in.
So the point of that section is that it will only be called when a new document is created as there is no need to update those fields with the same information every time. In addition to this, the fields you specified in the query criteria have explicit values, so the behavior of the "upsert" is to automatically create those fields with those values in the newly created document.
After a new document is created, then the next "upsert" statement that uses the same criteria will of course only "update" the now existing document, and as such only your new course information would be added.
Overall working like this allows you to "pre-join" the two tables from your source with an appropriate query. Then you are just looping the results without needing to write code for trying to group the correct entries together and simply letting MongoDB do the accumulation work for you.
Of course you can always just write the code to do this yourself and it would result in fewer "trips" to the database in order to insert your already accumulated records if that would suit your needs.
As a final note, though it does require some additional complexity, you can get better performance out of the operation as shown by using the newly introduced "batch updates" functionality.For this your MongoDB server version will need to be 2.6 or higher. But that is one way of still reducing the logic while maintaining fewer actual "over the wire" writes to the database.
You can either have two separate collections - one with student details and other with courses and link them with "id".
Else you can have a single document with courses as inner document in form of array as below:
{
"FirstName": "Fred",
"LastName": "Zhang",
"age": 20,
"id": "s1234",
"Courses": [
{
"courseId": "COSC2406",
"semester": 1
},
{
"courseId": "COSC1127",
"semester": 1
},
{
"courseId": "COSC2110",
"semester": 1
},
{
"courseId": "COSC2110",
"semester": 2
}
]
}

Can you GET Rally API requirements, defects, and all tasks with one query

Currently I have to make multiple GETs to receive all the information which I need
User Story: FormattedID, _refObjectName, State, Owner._refObjectName
Tasks for each User Story: FormattedID, _refObjectName, State, Owner._refObjectName
Defect: FormattedID, _refObjectName, State, Owner._refObjectName
Tasks for each Defect: FormattedID, _refObjectName, State, Owner._refObjectName
For all of the User Stories I use:
https://rally1.rallydev.com/slm/webservice/1.26/hierarchicalrequirement.js?query=((Project.Name = "[projectName]") and (Iteration.Name = "[iterationName]"))&fetch=true&start=1&pagesize=100
For all of the Defects I use:
https://rally1.rallydev.com/slm/webservice/1.26/defects.js?query=((Project.Name = "[projectName]") and (Iteration.Name = "[iterationName]"))&fetch=true&start=1&pagesize=100
Within each of these, if they have any Tasks, they display as:
{
"_rallyAPIMajor": "1",
"_rallyAPIMinor": "26",
"_ref": "https://rally1.rallydev.com/slm/webservice/1.26/task/9872916743.js",
"_refObjectName": "Update XYZ when ABC",
"_type": "Task"
}
This doesn't have all the information I need, so I hit each of the Tasks' _ref URLs to get the full task information.
This adds up to sometimes 80+ AJAX calls per page load.
Is there a better query which would provide the extra Task information up front?
The fetch parameter can be tricky with queries. If you provide fetch=true you will get all of the fields that exist on the queried type (Story,Defect). If the field is also a domain object (like a tasks or a defect) you will only get the thin ref object like this
{
"_ref": "/task/1234.js"
}
If you want to get fields populated on the sub-objects you will need to specify the fields you want shown in the fetch param fetch=Name,FormattedID,Tasks. This would return an object like the one below:
{
"HierarchicalRequirement" : {
"Name" : "StoryName",
"FormattedID" : "S1234",
"Tasks" : [
{
"_rallyAPIMajor": "1",
"_rallyAPIMinor": "26",
"_ref": "https://rally1.rallydev.com/slm/webservice/1.26/task/9872916743.js",
"_refObjectName": "Update XYZ when ABC",
"_type": "Task",
"FormattedID" : "T1",
"Name" : "Update XYZ when ABC"
}
]
}
}
Let me know if that helped