Let's say I have a JSON structure that contains the following:
{
"ROWS": [{
"name": "Greg",
"age": "24",
},
{
"name": "Tom",
"age": "53",
}]
}
The value for the key "ROWS" is a list of dictionaries, right?
Okay, well what if I only have one entry? Is it still appropriate to use list notation, even if that list has a single element?
{
"ROWS": [{
"name": "Greg",
"age": "24",
}]
}
Would there be any reason I could NOT do this?
There is no technical reason why you could not use a list. Your array could be empty and that's perfectly acceptable and valid technically.
For your ROWS property I think the most important thing to consider is how many rows you could possibly have. You want to incorporate the computer engineering principle of generality to make sure you don't paint yourself into a corner by making ROWS an object. If you can expect to ever have more then one object as a row, even if currently there is only one, then it's absolutely appropriate to use an array.
For example let's assume you expect to get a unique record such as a login system. Then it wouldn't make sense to use an array , in this case you should use an object instead
{
"LOGIN_ROW": {
"name": "Greg",
"age": "24",
}
}
Again I said should because it's up to you to format your json object graph. But of course if you have a scenario where you have a list of employees then it would make sense to use an array:
{
"LIST_OF_ROWS": [{
"name": "Greg",
"age": "24",
}]
}
This is perfectly fine because you have one employee at this time but you wish to expand your company so you would expect to get more employees.
Related
I have the following JSON
{
"items": [
{
"configurationStatus": "SYNCED",
"conflictDetectionState": "IN_SYNC",
"connectivityState": "ONLINE",
I can access individual elements inside with items[*].isModel, but, I cannot figure out how to access the first 3 elements. I tried something like this items[*].[0:2], but it didn't work. I am curious how to access the first 3 elements using slicing.
You would possibly face some issue trying to achieve this because, as pointed in the JMESPath documentation, object are:
object (an unordered collection of key value pairs)
Source: https://jmespath.org/specification.html, emphasis, mine
So you might end up with different keys based on the implementation and have really random results.
Now the issue with your approach is that slices can only act on arrays.
A slice expression allows you to select a contiguous subset of an array.
Source: https://jmespath.org/specification.html#slices, emphasis, mine
What you could do then, in order to have an array out of a hash is to use the values function, but mind that you'll lose the key/value association in the process.
Then, given you have an array, you can now apply the slicing technique.
So with the query:
items[].values(#)[0:3]
On the JSON:
{
"items": [
{
"configurationStatus": "SYNCED",
"conflictDetectionState": "IN_SYNC",
"connectivityState": "ONLINE",
"foo": "bar",
"baz": "qux"
},
{
"configurationStatus": "SYNCED′",
"conflictDetectionState": "IN_SYNC′",
"connectivityState": "ONLINE′",
"foo": "bar′",
"baz": "qux′"
}
]
}
This would give:
[
[
"SYNCED",
"IN_SYNC",
"ONLINE"
],
[
"SYNCED′",
"IN_SYNC′",
"ONLINE′"
]
]
What is the difference between these two JSON formats? Which format should I use?
[{
"employeeid": "12345",
"firstname": "joe",
"lastname": "smith",
"favoritefruit": "apple"
}, {
"employeeid": "45678",
"firstname": "paul",
"lastname": "johnson",
"favoritefruit": "orange"
}]
OR
[
["employeeid", "firstname", "lastname", "favoritefruit"],
["12345", "joe", "smith", "apple"],
["45678", "paul", "johnson", "orange"]
]
Definately first one. It will create array of employee object while second one will create array of array of objects which will be more difficult to parse in most of language.
It depends on the context.
The first is much easer to parse if you want to create employee objects to work with.
The second may be better if you need to work on the "raw" data only. Furthermore the second is much shorter. That's not important for small or medium datasets, but could be important for example if you need to transfer large sets of employee data.
Is there a way to update a complex MongoDB document from C# using JSON? For example, suppose I have the following document:
{
"name": "John Smith",
"age": 35,
"readingList":
[{
"title": "Title1",
"ISBN": 6246246426724,
"author":
{
"name": "James Johnson",
"age": 40
}
},
{
"title": "Title2",
"ISBN": 3513531513551,
"author":
{
"name": "Sam Hill",
"age": 20
}
}]
}
Now I want to update the age of the second book's author (Sam Hill) from 20 to 21. Suppose I have the following JSON representation:
{
"readingList":
[
{
"title": "Title2",
"author":
{
"age": 21
}
}]
}
Basically the second JSON string is like the first one, minus all the fields and array elements that don't change, except for one field in any array being looked at that uniquely identifies that index. In this case, the "age" field is included since it is being updated with the given value. The "title" field is given to locate the right array element while searching for the field to update. There may also be even more subdocuments and arrays to go through, and the format is not static (it may change at a later time). This is just a simplified example.
Is it possible to pass in something like this to some function and update the correct field that way? Is there something at least similar to this, so I can just pass in some JSON to do the update?
The reason I am looking to do it this way, rather than through simpler means, is because I want to keep track of a history of changes to documents, and if I want to backtrack to an earlier version, I want an easy way to do so that can handle this level of complexity.
UPDATE:
I have some clarifications to make. In this particular scenario I have no way to predict what kinds of changes would need to be made. A change could be made to any field at any time, and that field could be anywhere in the document, possibly at the top level, or within multiple nested subdocuments/arrays. The data we're dealing with is for a separate party that may use it and modify it at will, so we have no control over what they choose to do with it. In addition, there is no fixed schema. The other party could add new fields, including new subdocuments or arrays, or delete them.
The reason I'm asking this question is because I would like to store a history of changes to documents in such a way that I could revert to an older snapshot of the document by applying the changes in reverse. In this case, changing the age from to 20 to 21 would revert the document to an older state (assuming that someone messed with the age beforehand and made it 20, and I wanted to fix it back to 21). Since somebody could make any change they wanted to the system, including to the underlying structure of the data itself, I can't just come up with my own schema, or hardcode a solution that changes specific fields using this specific schema.
In this example, the change in age from 20 to 21 would be from a record in the history whose structure I couldn't predict beforehand. So I am looking for an efficient solution to apply an unpredictable update to a document given a simplified JSON representation of the change to be made.
I am also open to alternatives that don't involve JSON if they are fairly efficient. I brought up JSON because I figured that, given MongoDB's usage of JSON to structure documents, it would make the most sense, and perhaps be superior to something like string manipulation. Another alternative I considered would involve storing the change using some kind of custom dot notation, like this: readingList[ISBN:3513531513551].author.age=21"
This would require me to create a custom function to interpret the string and turn it into something useful though, so it doesn't sound like the best solution.
Hi friend I used below JSON document
{
"_id" : ObjectId("56a99c121f25cc3a3c709151"),
"name" : "John Smith",
"age" : 35,
"readingList" : [
{
"title" : "Title1",
"ISBN" : NumberLong(6246246426724),
"author" : {
"name" : "James Johnson",
"age" : 40
}
},
{
"title" : "Title2",
"ISBN" : NumberLong(3513531513551),
"author" : {
"name" : "Sam Hill",
"age" : "25"
}
}
]
}
I just used condition as author name is Sam Hill and execute below query in C# and its work.
IMongoQuery query = Query.And(Query.EQ("name", "John Smith"), Query.EQ("readingList.author.name", "Sam Hill"));
var result =collection.Update(query,
MongoDB.Driver.Builders.Update.Set("readingList.$.author.age", "21"));
you can query your main document let's assume your main collection is named "books" this is the structure:
{
"id":"123",
"name": "John Smith",
"age": 35,
"readingList":
[{
"title": "Title1",
"ISBN": 6246246426724,
"author":
{
"name": "James Johnson",
"age": 40
}
},
{
"title": "Title2",
"ISBN": 3513531513551,
"author":
{
"name": "Sam Hill",
"age": 20
}
}]
}
// you need a query that returns the main document by id for example, when you have the main document you can query at the one you want to modify in the list and assing it to a varibale let's say readItem, then do the modifications you need and after that you can update only the fields you need using set and onle the element in the array using "$" something like:
readItem.title = "some new title";
readItem.age++;
var update = MongoDB.Driver.Builders.Update.Set("readingList.$", BsonDocumentWrapper.Create(readItem));
Update<Book>(query, update);
Actually I would not advise you to choose this kind of data model because in my experience it will get pretty messy. Still, you might have some very specific requirements which might force you to have this and only this data model.
I would create two collections: persons and readinglists.
persons would look like:
{
"id":"123",
"name": "John Smith",
"age": 35
}
and readinglists would look like (note that it has a compound natural id):
{
"_id": { "personid":"123", "title": "Title1"},
"ISBN": 6246246426724,
"author":
{
"name": "James Johnson",
"age": 40
}
}
Then you can easily update the readinglist:
var query = Query.EQ("_id", new BsonDocument(new BsonElement[]{ new BsonElement("personid":"123"), BsonElement("title":"Title1")}));
readingListCollection.Update(query, Update.Set("author.age": 22));
In your data mode you need to know the array index of the second document. It is better to model readingList attribute as a map. In following example I used isbn as a map key:
{
"id":"123",
"name":"John Smith",
"age":35,
"readingList":{
"6246246426724":{
"title":"Title1",
"ISBN":6246246426724,
"author":{
"name":"James Johnson",
"age":40
}
},
"3513531513551":{
"title":"Title2",
"ISBN":3513531513551,
"author":{
"name":"Sam Hill",
"age":20
}
}
}
}
In this data model you can access second book directly. For instance by dot notation:
db.authors.update(
{ item: "123" },
{ $set: { "readingList.3513531513551.author.age": 22 } }
)
Unfortunately I do know C# notation for that but should be straight forward.
How does bind values of embedded JSON data to input elements in EmberJS as I cannot seem to find a straight forward way to get that done.
update
It doesn't seem to work for a JSON object with this structure
{
"users": [
{
"_id": "534550428047526419000002",
"Name": "admin",
"Code": "admin",
"Age": 12,
"Sex": "Male",
"Ethnicity": "admin",
"EventTime": "",
"Accident": [
{
"value": true,
"risk": "Medium"
}
]
}
]
}
In the template you use the property name
{{foo}}
{{input value=foo}}
Example
http://emberjs.jsbin.com/wufegaca/1/edit
nested properties are handled the same way they are in most languages with the dot operator
{{foo.bar}}
{{input value=foo.bar}}
Example
http://emberjs.jsbin.com/wufegaca/2/edit
Using an array you need to iterate over the array. If you didn't how would Ember know which item you were referring to? Additionally upper case property names are problematic in handlebars, since it usually denotes a global namespace, so be wary if things don't appear to be working.
Example
http://emberjs.jsbin.com/wufegaca/3/edit
I have a REST service that returns a list of objects. Each object contains objectcode and objectname.
This is my first time building a REST service, so I'm not sure how to format the response.
Should it be:
{
"objects": {
"count": 2,
"object": [
{
"objectcode": "1",
"objectname": "foo"
},
{
"objectcode": "2",
"objectname": "bar"
},
...more objects
]
}
}
OR
[
{
"objectcode": "1",
"objectname": "foo"
},
{
"objectcode": "2",
"objectname": "bar"
},
...more objects
]
I realize this might be a little subjective, but which would be easier to consume? I would also need to support XML formatted response later.
They are the same to consume, as a library handles both just fine. The first one has an advantage over the second though: You will be able to expand the response to include other information additional to the objects (for example, categories) without breaking existing code.
Something like
{
"objects": {
"count": 2,
"object": [
{
"objectcode": "1",
"objectname": "foo"
},
{
"objectcode": "2",
"objectname": "bar"
},
...more objects
]
}
"categories": {
"count": 2,
"category" : [
{ "name": "some category"}
]
}
}
Additionally, the json shouldn't be formatted in any way, so remove whitespace, linebreaks etc. Also, the count isn't really necessary, as it will be saved while parsing the objects themselves.
I often see the first one. Sometimes it's easier to manipulate data to have meta-data. For exemple google API use first one : http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true
It's not only the question of personal preference; it's also the question fo your requirements. For example, if I was in the same situation and I did need object count on client side then I'd go with first approach otherwise I will choose the second one.
Also please note that "classic" REST server mostly will work a bit different way. If some REST function is to return a list of objects then it should return only a list of URLs to those objects. The URLs should be pointing to details endpoints - so by querying each endpoint you may get details on specific single object.
As a client I would prefer the second format. If the first format only includes the number of "objects", this is redundant information.