I have some documents in CouchDB of type: "Person" and of type "Account".
For a straight list of all documents of these types I have created the following design document in _design/directory_views:
{
"_id": "_design/directory_views",
"_rev": "21-f5df9253504e66f28393f4bda360e110",
"views": {
"all_persons": {
"map": "(function(doc) { if (doc.type == \"Person\") { emit(null, { 'last_name': doc.last_name, 'first_name': doc.first_name }); } })"
},
"all_accounts": {
"map": "(function(doc) { if (doc.type == \"Account\") { emit(null, { 'username': doc.username }); } })"
}
}
}
This JSON validates on JSONLint and is accepted when saving the document in Futon's source view.
Futon lists directory_views/all_persons and directory_views/all_accounts as expected in the dropdown. all_persons creates the correct list of documents of type "Person", however all_accounts redirects back to the toplevel All Documents, and lists everything.
Why does all_persons work, but all_accounts fail?
PS. I've experienced this behavior on a number of design documents so far. This example http://kore-nordmann.de/blog/couchdb_a_use_case.html#a-practical-example shows two views in the same design document, so I don't think that you can only have one view per document.
Try accessing your view directly (ie. outside of Futon) to see if it behaves the same way.
Related
I'm writing a google doc using the google docs api, and I found that there is a json 'dump' feature that helps you understand the structure of your google doc.
The only problem is, the JSON dump is different than the JSON used to actually write the doc.
For example, this is where I found out about the JSON dump:
https://developers.google.com/docs/api/samples/output-json
The truncated JSON example looks like this:
{
"body": {
"content": [
{
"endIndex": 1,
"sectionBreak": {
"sectionStyle": {
"columnSeparatorStyle": "NONE",
"contentDirection": "LEFT_TO_RIGHT"
}
}
},
{
"endIndex": 75,
"paragraph": {
"elements": [
{
"endIndex": 75,
"startIndex": 1,
"textRun": {
"content": "This is an ordinary paragraph. It is the first paragraph of the document.\n",
"textStyle": {}
}
}
],
"paragraphStyle": {
"direction": "LEFT_TO_RIGHT",
"namedStyleType": "NORMAL_TEXT"
}
},
"startIndex": 1
},
And here is documentation for making update requests to your document:
https://developers.google.com/docs/api/reference/rest/v1/documents/request
Basically what I'm seeing is that the two have some general structures in common, but the notation for actually writing the JSON is different.
For instance, here's an example of how to write to the document:
const updateObject = {
documentId: 'documentID',
resource: {
requests: [ {
insertText: {
text: 'hello world',
location: {
index: 1,
},
},
} ],
},
};
I'm hoping there is a way I can write the json in the same way that the dump is structured, and then pass that format through to create new documents. Otherwise I'm going to have to tediously translate everything from one format to the other (and there's a lot),
Does anyone have any advice on this? Maybe there is something I'm missing. Thanks!
It appears to be intended. The JSON dump in the example matches the Document object. You can also find this same structure returned when you create a document via thedocuments.create API. Unfortunately, pretty much all of the fields are output-only. I tried to plug in the body from the sample into the API, and while it didn't fail, it also ignored the input and just created a basic document.
Meanwhile, the batchUpdate methods that you found to send update requests all seem focused on specific changes and none of them take a Document object. I think your best bet would be to follow up the feature request that you found, the Docs API is still considered in v1 after all.
This issue is a bit tricky to describe so bear with me and please ask questions if I am missing anything...
Say you have a json object that defines a list of features, each feature has a the same three properties but has a property that has an entirely different structure. For example:
{
features: [
{
id: "feature-a",
enabled: true,
configurationData: {
featureAConfigPropertyA: {
somePrperty: "whatever",
anotherProperty: true
},
featureAConfigPropertyB: "some string"
}
},
{
id: "feature-b",
enabled: true,
configurationData: {
featureBConfigArrayPropertyA: ["some string"],
featureBConfigPropertyB: [
{
"id": "some string",
"name": "some string",
"description": "some string",
"enabled": true
}
]
}
}
]
}
The actual structure of each feature is irrelevant. I am just trying to express this via json schema whereby the structure of configurationData for each feature is dependent on or dictated by the feature id value of its parent.
EDIT: I guess technically it doesnt need to be dependent on so long as either structure of configurationData is valid schema for that property on the feature schema itself. Also, the types in configurationData arent arbitrary, they would always be one of the two types for a given feature in this example.
This however needs to be structured in a way that can be expressed via Formly as I am using this to generate forms. In this case it would be an array of ObjectFieldTypes, one for feature a and one for feature b, which would enumerate the three properties and provide Input field types, until it got to configurationData at which point it would use an ObjectFieldType again, which would now be different for each field type.
The issue here is that 1) I'm not sure how to express this in json schema and 2) I can't use things like patternProperties with formly because the properties have to be explicitly defined in the json schema in order for formly to render the field types for each property. Although patternProperties would technically be valid schema in this case, if the schema doesn't define those properties, then the model in the valueChanges observable on the FormGroup just excludes them entirely. So I would end up with:
{
features:[
{
id: "feature-a",
enabled: true,
configurationData: { }
},
{
id: "feature-b",
enabled: true,
configurationData: { }
}
]
}
I have tried the if then else construct, but I cant tell if the schema is wrong or if formly just doesn't support this. I made a stack blitz for this below:
https://stackblitz.com/edit/angular-g45ydm?file=src%2Fassets%2Fjson-schema%2Fif_then.json
I've been wondering for some days what kind of scheme would be more appropriate to use a data list in json in a web application.
I'm developing a REST Web Application, and im using Angular for front end, i should order, filter and print these data list also in xml ...
For you what scheme is better and why?
1) {
"datas": [
{ "first":"","second":""},
{ "first":"","second":""},
{ "first":"","second":""}
]
}
2) {
"datas": [{
"data": { "first":"","second":""},
"data": { "first":"","second":""},
"data": { "first":"","second":""}
}]
}
3) [
{ "first":"","second":""},
{ "first":"","second":""},
{ "first":"","second":""}
]
Thanks so much.
The first and third notations are quite similar because the third notation is included in your first.
So the question is "Should I return my datas as an array or should I return an object with a property that contain the array ?
It will depend on either you want to have more information alongside your datas or not.
For exemple, if your API might return an error, you will want to manage it from the front end.
In case of error, the JSON will looks like this :
{
"datas": null,
"error": "An error occured because of some reasons..."
}
At the opposite, if everything goes well and your API actually return the results, it will looks like this :
{
"datas": [
{ "first":"","second":""},
{ "first":"","second":""},
{ "first":"","second":""}
],
"error": null
}
Then your front end can use the error property to manage errors sent from the API.
var result = getDatas(); // Load datas from the API
if(result.error){
// Handle the error, display a message to the user, ...
} else {
doSomething(result.datas); // Use your datas
}
If you don't need to have extra properties like error then you can stick with the third schema.
The second notation is invalid. The datas array will contain only one object which will have one property named data. In this case data is a property that is defined multiple times so the object in the array will contain only the last occurence:
var result = {
"datas": [{
"data": { "first":"a","second":"b"},
"data": { "first":"c","second":"d"},
"data": { "first":"e","second":"f"}
}]
}
console.log("Content of result.datas[0].data : ")
console.log(result.datas[0].data)
Obviously the first option would be easy to use. Once you will access datas it'll give you an array. Any operation (filter, sort, print) on that array will be easy in comparison to anything else. Everywhere you just need to pass datas not datas.data.
I am trying to create a view in Cloudant DB which will pick up all the JSON documents based on the value of one field (SAVE_TYPE_SUBMIT). My problem is that, the JSON document contains nested fields. Please take a look at the sample document below.
{
"_id ": "70f79cc9309fd8b2bcca90efd871f993 ",
"_rev": "1-18fe726fc3d99f50a945ab30c9ffeb4b",
"NAME": "qqq",
"EMAIL": "qqq",
"TITLE": "qq",
"DATE_OF_REPORT": "2017/08/17",
"PUBLIC_OFFICIALS_CONTACTED": [{
"NAME_PUBLIC_OFFICIAL": "qq"
},
{
"TITLE_PUBLIC_OFFICIAL": "qq"
}
],
"MANAGER": "qq",
"SAVE_TYPE_SUBMIT": "Submit"
}
The view created is :
function(doc) {
if (("SAVE_TYPE_SUBMIT" in doc) && (doc.SAVE_TYPE_SUBMIT == "Submit")) {
emit (doc.LAST_UPDATE_BY, [doc.NAME, doc.EMAIL, doc.TITLE, doc.DATE_OF_REPORT, doc.PUBLIC_OFFICIALS_CONTACTED, doc.MANAGER]);
}
}
When I try to fetch the data from this view into my application, I do not get the value of the nested fields, i.e. NAME_PUBLIC_OFFICIAL and TITLE_PUBLIC_OFFICIAL. I see those fields as [object,object].
Please note that PUBLIC_OFFICIALS_CONTACTED can contain multiple Name and Title fields.
Please help understand how the view needs to be customized to get the value of the nested fields. I am having a hard time with this and any guidance or material will be highly appreciated!
Create a map function of this form:
function(doc) {
if (("SAVE_TYPE_SUBMIT" in doc) && (doc.SAVE_TYPE_SUBMIT == "Submit")) {
emit(doc.LAST_UPDATE_BY, { name:doc.NAME, email: doc.EMAIL, title: doc.TITLE, date: doc.DATE_OF_REPORT, officials: doc.PUBLIC_OFFICIALS_CONTACTED, manager: doc.MANAGER});
}
}
This is very similar to your map function except that it emits a value which is an Object instead of an array. This object can represent a subset to the original document.
If you need ALL the fields from the original document, then you could modify the function to:
function(doc) {
if (("SAVE_TYPE_SUBMIT" in doc) && (doc.SAVE_TYPE_SUBMIT == "Submit")) {
emit(doc.LAST_UPDATE_BY, null);
}
}
and add ?include_docs=true when querying the view to add the original document bodies to the response.
In older versions of breeze when I analyze the breeze metadata file, I'd see a format that shows a detailed json format of metadata that describes the DBContext.
So an example from Breeze's sample would be something like this:
{
"schema":{
"namespace":"Todo.Models",
"alias":"Self",
"annotation:UseStrongSpatialTypes":"false",
"xmlns:annotation":"http://schemas.microsoft.com/ado/2009/02/edm/annotation",
"xmlns":"http://schemas.microsoft.com/ado/2009/11/edm",
"cSpaceOSpaceMapping":"[[\"Todo.Models.TodoItem\",\"Todo.Models.TodoItem\"]]",
"entityType":{
"name":"TodoItem",
"key":{
"propertyRef":{
"name":"Id"
}
},
"property":[
{
"name":"Id",
"type":"Edm.Int32",
"nullable":"false",
"annotation:StoreGeneratedPattern":"Identity"
},
{
"name":"Description",
"type":"Edm.String",
"maxLength":"30",
"fixedLength":"false",
"unicode":"true",
"nullable":"false"
},
{
"name":"CreatedAt",
"type":"Edm.DateTime",
"nullable":"false"
},
{
"name":"IsDone",
"type":"Edm.Boolean",
"nullable":"false"
},
{
"name":"IsArchived",
"type":"Edm.Boolean",
"nullable":"false"
}
]
},
"entityContainer":{
"name":"TodosContext",
"entitySet":{
"name":"Todos",
"entityType":"Self.TodoItem"
}
}
}
}
But now after running this new version of breeze, and hitting my metadata file I see this weird oddity:
{
"?xml":{
"version":"1.0",
"encoding":"utf-8"
},
"schema":{
"namespace":"DBModel",
"alias":"Self",
"annotation:UseStrongSpatialTypes":"false",
"xmlns:annotation":"http://schemas.microsoft.com/ado/2009/02/edm/annotation",
"xmlns:customannotation":"http://schemas.microsoft.com/ado/2013/11/edm/customannotation",
"xmlns":"http://schemas.microsoft.com/ado/2009/11/edm",
"cSpaceOSpaceMapping":"[[\"DBModel.User\",\"Model.User\"]]",
"entityContainer":{
"name":"DBEntities",
"annotation:LazyLoadingEnabled":"true",
"entitySet":{
"name":"Users",
"entityType":"DBModel.User"
}
},
"entityType":{
"name":"User",
"key":{
"propertyRef":{
"name":"Id"
}
},
"property":[
{
"name":"Id",
"type":"Edm.Int64",
"nullable":"false",
"annotation:StoreGeneratedPattern":"Identity"
},
{
"name":"Firstname",
"type":"Edm.String",
"maxLength":"40",
"fixedLength":"false",
"unicode":"false"
},
{
"name":"Lastname",
"type":"Edm.String",
"maxLength":"60",
"fixedLength":"false",
"unicode":"false"
},
{
"name":"Email",
"type":"Edm.String",
"nullable":"false",
"maxLength":"128",
"fixedLength":"false",
"unicode":"false"
}
]
}
}
}
What's the point in including the xml information within the metadata? How is breeze able to pick up information from the metadata between these two versions and still work as it does?
The EFContextProvider (in breeze.server.net) basically just converts the metadata information from EntityFramework from XML to JSON, and sends that back to the Breeze client. The Breeze client knows how to get what it needs from that JSON format, even when there are some extra XML-related bits tacked on.
Basically, Breeze ignores the parts that aren't relevant. In newer versions of EF, the extra stuff in the XML has expanded, but the basic structure has remained the same.