Emit couchbase data - couchbase

I would like to emit couchbase data in the following format :
rows: [
{
id: "UniqueID",
key: "UniqueKey",
doc: {
meta: {
id: "UniqueID"
},
json: {
//ACTUAL DOCUMENT HERE
}
}
}
,
.... Second document and so on
When I try to create a view :
function (doc, meta) {
emit(meta.id, doc);
}
It emits the data in the following fashion :
total_rows: 55, -- DO NOT NEED THIS
rows: [
{
id: "UniqueID",
key: "UniqueKey",
value: {
//ACTUAL DOCUMENT HERE
}
},
.... Second document and so on
How do I modify the view to output the exact same schema as mentioned above ?

You don't. View response follows a defined format that tools like the SDKs rely on for parsing.
Also it is generally not a good idea to emit the whole document: since the value of the view get stored in the secondary index, you are basically duplicating all your data in the key/value store and the view index...
View responses always include the document ID for a particular row, so you can always get the document by performing a key/value GET. The SDKs can also abstract that away in their API (eg. in Java there's a document() method on each row object).

Related

Monaco editor default json uri schema

I'm using monaco editor to edit JSON and I would like to set a custom diagnostic option.
I'm trying that https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-configure-json-defaults
// Configures two JSON schemas, with references.
var jsonCode = [
'{',
' "p1": "v3",',
' "p2": false',
"}"
].join('\n');
var modelUri = monaco.Uri.parse("a://b/foo.json"); // a made up unique URI for our model
var model = monaco.editor.createModel(jsonCode, "json", modelUri);
// configure the JSON language support with schemas and schema associations
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
validate: true,
schemas: [{
uri: "http://myserver/foo-schema.json", // id of the first schema
fileMatch: [modelUri.toString()], // associate with our model
schema: {
type: "object",
properties: {
p1: {
enum: ["v1", "v2"]
},
p2: {
$ref: "http://myserver/bar-schema.json" // reference the second schema
}
}
}
}, {
uri: "http://myserver/bar-schema.json", // id of the second schema
schema: {
type: "object",
properties: {
q1: {
enum: ["x1", "x2"]
}
}
}
}]
});
monaco.editor.create(document.getElementById("container"), {
model: model
});
Where does uri: "http://myserver/foo-schema.json" come from ? I just want to use default JSON schema. Not my own.
Setting uri like this works :
uri: "http://localhost:4200/assets/monaco-editor/min/vs/language/json/jsonMode.js",
But is there a clean way to set this value ? Maybe uri value for JSON is available somewhere ? I searched through monaco.languages.json.jsonDefaults but I did not find anything.
"http://myserver/foo-schema.json" is an arbitrary value-- you can make it anything you want. It only matters if you are also using enableSchemaRequest-- in which case it should point to the location that you want the schema to be fetched from-- but you're not doing that, so that doesn't matter. In fact, everything related to this URI is irrelevant to what you are trying to do, if I'm understanding your intent correctly.
When you say "I just want to use default JSON Schema, Not my own", I think what you mean to say is that you just want to ensure that it is valid JSON, right? Because, there is no such thing as "default JSON Schema"-- by definition, it is defined by you-- but there is such a thing as a formal definition of what JSON is (JSON Schema, on the other hand, assumes that you are already starting with valid JSON, and allows you to then define a schema that your (valid) JSON must conform to).
Assuming you just want to ensure it is valid JSON (but you don't care that the json conform to some custom schema), setting the language to 'json' is all you need to do and your code can be as simple as:
var myBadJSONText = '{this is not : "JSON"}'
monaco.editor.create(document.getElementById('container'), {
language: 'json',
value: myBadJSONText
});
which running in the Monaco playground gives you:

cloudant view for nested json documents

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.

Couchbase View not returning array value

I am trying to create a view to group on a particular attribute inside an array. However, the below map function is not returning any result.
JSON Document Structure :
{
"jsontype": "survey_response",
"jsoninstance": "xyz",
"jsonlanguage": "en_us",
"jsonuser": "test#test.com",
"jsoncontact": "test#mayoclinic.com",
"pages": [
{
q-placeholder": "q1-p1",
q:localized": "q1-localized-p1",
q-answer-placeholder": "jawaabu121",
q-answer-localized": "localized jawaabu1"
},
{
q-placeholder": "q2-p2",
q:localized": "q2-localized-p2",
q-answer-placeholder": "jawaabu221",
q-answer-localized": "localized jawaabu2"
},
{
"q-placeholder": "q3-p3",
"q:localized": "q3-localized-p3",
"q-answer-placeholder": "jawaabu313",
"q-answer-localized": "localized jawaabu3"
}
]
}
Map Function :
function(doc, meta){
emit(doc.jsoninstance,[doc.pages[0].q-placeholder, doc.pages[0].q-localized,doc.pages[0].q-answer-placeholder,q-answer-localized]);
}
It looks like you made a typo at the end of your emit statement:
doc.pages[0].q-answer-placeholder,q-answer-localized.
Instead q-answer-localized should be changed to doc.pages[0].q-answer-localized.
Further to this it seems that you have defined a field as q-localized in your emit statement, but actually according to the sample document that you posted this should actually be q:localized, I assume that this was a mistake in the snippet of the document and not the emit statement, but if not then will also need amending.
I would imagine errors like this would be flagged up in the view engine's map-reduce error log, in future you should check this log so that you will be able to debug errors like this yourself.
The location of the mapreduce_errors log can be found in the Couchbase documentation

Sending complex JSON with fetch, save, and delete on a model or collection

We have an internal API that was specifically built to be used with a new piece of software I'm building that runs on Backbone. The API has a single URL and takes JSON as input to determine what it needs to return. It essentially allows me to build custom queries with JSON that return exactly what I'm looking for.
Thing is this JSON can get pretty verbose and is often 3–4 levels deep, but sometimes may just be a few lines and just 1 level deep.
First question first: How do I send a string of JSON along with the ID when I do a fetch()? Do I have to set these parameters as the model or collection's defaults?
Here is an example of a really simple string to get a specific user's info
{
"which" : "object",
"object" : {
"type" : "customer",
"place" : "store",
"customerID" : "14"
}
}
As others have suggested it will likely be challenging to work with SOAP, but it shouldn't be impossible. Backbone models and collections communicate with the server through the sync operation; you should be able to customize that. I think something along these lines might get the ball rolling (for models):
Backbone.SoapyModel = Backbone.Model.extend({
sync: function(method, model, options) {
// force POST for all SOAP calls
method = 'create';
options = _.extend(options, {
// Setting the data property will send the model's state
// to the server. Add whatever complexity is needed here:
data: JSON.stringify({
"which" : "object",
"object" : model.toJSON()
}),
// Set the request's content type
contentType: 'application/json'
});
// Defer the rest to Backbone
return Backbone.sync.apply(this, [method, model, options]);
}
});
var SoapyModelImpl = Backbone.SoapyModel.extend({
url: '/test'
});
var soapTest = new SoapyModelImpl({
id: 42,
name: 'bob',
address: '12345 W Street Dr',
phone: '867 5304'
});
soapTest.fetch();

node.js template to convert JSON objects

I would like to use some expression language in JSON objects. Let's say I have a "template" like:
jsonTemplate = {
title:"Title: '#{title}',
header: "Created by #{meta.author} at #{meta.createdAt}"
}
and the actual data as follows:
data = {
title: "Some title",
content:"bla...",
meta: {createdAt:new Date(), author:"me"}
}
I would like to do something similar to
parser.render(jsonTemplate, data);
to return
{
title:"Title: 'Some title'",
header: "Created by me at 2012-05-10 10:00:00"
}
All the template engines focus on html generation, but the result of the "render" step should be a json object.
Is there any engine which allows this?
If not, I would create the json object myself and apply an existing engine to the single attributes. Would you recommend an engine for this?
Ideally this should be available as node.js module or common.js.