I have documents in my bucket:
{ type: "post", author: "1", subject: "s1", timestamp: 11}
{ type: "post", author: "1", subject: "s2", timestamp: 12}
{ type: "post", author: "2", subject: "s3", timestamp: 9 }
{ type: "post", author: "3", subject: "s4", timestamp: 10}
{ type: "post", author: "4", subject: "s5", timestamp: 14}
{ type: "post", author: "5", subject: "s6", timestamp: 11}
I have got view:
function(doc, meta) {
if(doc.t === 'post') {
emit([doc.timestamp, doc.author]);
}
}
it gives me:
[11, "1"]
[12, "1"]
[9, "2"]
[10, "3"]
[14, "4"]
[11, "5"]
I want to select posts of specific users ["2","3","5"] ordered by timestamp.
I mean "get the newest posts of some users".
Is it possible to do?
I would re-organize your data:
Assuming your authors are unique, keep a document for each author and save their posts as a list within that doc.
doc name: "author:1"
doc:
{ 'posts':[{'subject':'s1','body':'this is body1'},
{'subject':'s2','body':'this is body2'}] }
The trick is to maintain order within the list of posts. Your view can pull the last item in the list of posts if you want only the latest post.
View key array deals with its (natural) order.
If you want to "specific" user: say, exact matched user with timestamp ordered, the view function would look like:
function(doc, meta) {
if(doc.type === 'post') {
emit([doc.author, doc.timestamp], null);
}
}
with this exact author 1, timestamp range 1~100
startkey: [1, 1]
endkey: [1, 100]
results:
[1, 11]
[1, 12]
BUT, if you want both attribute with range...
author: 1~10
timestamp: 1~100
It follows emitted 'ARRAY' order; more than 2 attribute with range query will not return as desired way.
If you want another type of sorted result with multiple "ranged" attribute, you should consist view function.
Related
I would like to format the output of my MongoDB query.
The following query
db.getCollection("books").find({})
returns the following json:
{
title: "book 1",
numberOfReaders: 3,
characters: [{
name: "annie",
age: 3,
height: 60,
items: {
itemName: "watch",
itemDesc: "tells time"
},{
name: "bob",
age: 5,
height: 100,
items: {
itemName: "sword",
itemDesc: "a long metallic sword"
}]
}
I realised that i can control the formatting for the JSON output using $ so the following query:
db.getCollection("books").find({},{
title: "$title",
numberOfReaders: "$numberOfReaders",
})
which returns the following json:
{
title: "book 1",
numberOfReaders: 3, // excludes the characters array
}
But how do I control the output of the json for nest arrays such that the output is as follows:
{
title: "book 1",
numberOfReaders: 3,
characters: [{ // removed age, height and itemDesc for all character objects
name: "annie",
items: {
itemName: "watch",
},{
name: "bob",
items: {
itemName: "sword",
}]
}
Furthermore, how do I do this if the characters array was wrapped around another array
{
title: "book 1",
numberOfReaders: 3,
characters: [[{ // removed age, height and itemDesc for all character objects, characters property are wrapped in two arrays
name: "annie",
items: {
itemName: "watch",
},{
name: "bob",
items: {
itemName: "sword",
}]]
}
One option that will work for single or double array, is:
db.getCollection("books").find({},
{
title: 1,
numberOfReaders: 1,
"characters.name": 1,
"characters.items.itemName": 1
})
See how it works on the playground example - single array
See how it works on the playground example - double array
I want to remove proxies fields like __initializer__: null,__cloner__: null, __isInitialized__: true, from my returned json but I have no idea.
I dont want to use * #Serializer\Exclude() because there are some more fields next to those fields.
here is a sample json:
emails: [
{
id: 1,
subject: "Mrs. Astrid Wuckert",
body: "Excepturi.",
sendCopy: false,
roles: [
{
__initializer__: null,
__cloner__: null,
__isInitialized__: true,
name: "ROLE_ADMIN"
},
{
name: "ROLE_RESELLER"
},
{
name: "ROLE_RETAILER"
},
{
name: "ROLE_CLUB_SHOP"
}
]
},
]
Thanks in advance.
Try call ignoring fields while creating normalizer:
$normalilzer->setIgnoredAttributes(["__initializer__", "__cloner__","__isInitialized__"]);
hi i am using MEAN STACK i want to validate JSON keys that comes from front end against mongoose schema. I am validating values but how shall i validate keys that com from client side for example.
var CategorySchema = new Schema({
name: {
type: String,
lowercase: true,
default: '',
trim: true,
unique: [true, 'Category name already exists'],
required: [true, 'Category Name cannot be blank'],
minlength: [4, 'Minimum 4 characters required'],
maxlength: [12, 'Category name cannot be That long']
},
parentCategory: {
type: String,
lowercase: true,
default: '',
trim: true
},
description: {
type: String,
lowercase: true,
default: '',
trim: true,
required: [true, 'description cannot be blank'],
minlength: [10, 'Very short description']
},
imageUrl: {
type: String,
default: '',
trim: true
}
});
what if i am providing this format
{
"IMAGEURL": "c:\abc.png", instead of imageUrl
"DESCRIPTION": "here is some description", INSTEAD OF description
"PARENTCATEGORY": "Men Wear", instead of parentcategory
"Name": "Shirts" instead of name
}
i am writing rest api that will be authenticated is it necessary to check these things. kindly help
For me json schema is so complicated. I suggest to use Json Pattern Validator
npm install jpv
it is very simple to use without any additional keys, and has many patterns to describe json.
import jpv from 'jpv';
var json = {
status : 'OK',
data : {
url : 'http://example.com'
}
}
var pattern = {
status : /^OK$/,
data : {
url : "[url]"
}
}
console.log( jpv.validate(json, pattern ) )
I have a JSON object which represents calendar data. I'm stuck on how, or if it is possible to add a create method to insert new data based on key value.
Here is my schema
year: {
August: [
{
day: String,
title: String,
summary: String,
description: String
}
],
September: [
{
day: String,
title: String,
summary: String,
description: String
}
]
}
});
I'd like to be able to create a new date based on the Key value, the Key being the month.
{
_id: "53d069cbea21639a67b5c64b"
__v: 0
-year: {
-September: [
-{
day: "9 sep"
title: "sep title"
summary: "sep summ"
_id: "53d069cbea21639a67b5c64c"
}
],
-August: [
-{
day: "9"
title: "Dave Ramsey's Financial Peace University"
summary: "Financial Peace University (FPU) is a biblically-based, life-changing program that teaches people how to make wise decisions with money. You will be empowered with the practical skills and confidence needed..."
_id: "53d069ccea21639a67b5c651"
}
-{
day: "17"
title: "Divorce & Beyond Seminar"
summary: "If you are separated from your spouse, going through a divorce or are divorced, we encourage you to seek support. We understand the feelings of guilt, rejection, fear, confusion, isolation,..."
_id: "53d069ccea21639a67b5c650"
}
]
}
}
Here is my current create method. Maybe everything is ok here and my work just needs to be done on the angular side....
module.exports.create = function (req, res) {
var cal = new Cal(req.body);
cal.save(function(err, result) {
if (err)
res.send(err);
res.json(result);
});
}
I'm currently returning new objects in postman with a new _id and empty values.
{
__v: 0
_id: "53ed6aa775e54f91b7362788"
-year: {
September: [ ]
August: [ ]
}
}
i have a json in the following format:
{
"collection": [
{
"id": 4,
"tickets": {
"collection": [
{
"inner_id": 8,
},
{
"inner_id": 10,
}
],
"count": 2,
"type": "collection"
},
},
{
"id": 5,
"tickets": {
"collection": [
{
"inner_id": 1,
},
{
"inner_id": 2,
}
],
"count": 2,
"type": "collection"
},
},
]
}
For this particular JSON i created the models as:
Ext.define("myProject.model.ABC", {
extend: "Ext.data.Model",
config: {
idProperty: "id",
fields:[
{name: "id", type: "int" },
],
hasMany: [
{
model: "myProject.model.XYZ",
name: "tickets",
associationKey: "tickets",
},
],
}
});
And second store as:
Ext.define("myProject.model.XYZ", {
extend: "Ext.data.Model",
config: {
// idProperty: "id",
fields:[
{name: "inner_id", type: "int" },
],
belongsTo: 'myProject.model.ABC'
}
});
But now i am confused. How do i populate the second store with a root property of collection again.
I know one way is to easily change the json so that there is no collection child inside tickets but i dont want to do that.
Any help would be appreciated. I have simplified the JSON for an easy example.
EDIT:
To be more clear, is there a way i can directly create a model which will read the Collection array inside the tickets object.
EDIT:
Adding the store which populates the model ABC for more understanding
Ext.define("myProject.store.ABCs", {
extend: "Ext.data.Store",
config: {
model: "myProject.model.ABC",
autoLoad: false,
proxy: {
type: "ajax",
url: '', //myURL
reader: {
type: "json",
rootProperty: "collection", // this is the first collection
},
},
}
});
This store loads the ABC model correctly but now i want to load the XYZ model which can load the inner array of collection
belongsTo should be define as follows :
Ext.define('Product', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', type: 'int' },
{ name: 'category_id', type: 'int' },
{ name: 'name', type: 'string' }
],
associations: [
{ type: 'belongsTo', model: 'Category' }
]
Have you read the doc? They specified the root property.
The name of the property which contains the data items corresponding to the Model(s) for which this Reader is configured. For JSON reader it's a property name (or a dot-separated list of property names if the root is nested). For XML reader it's a CSS selector. For Array reader the root is not applicable since the data is assumed to be a single-level array of arrays.
By default the natural root of the data will be used: the root JSON array, the root XML element, or the array.
The data packet value for this property should be an empty array to clear the data or show no data.
Sometimes the JSON structure is even more complicated. Document databases like CouchDB often provide metadata around each record inside a nested structure like this:
{
"total": 122,
"offset": 0,
"users": [
{
"id": "ed-spencer-1",
"value": 1,
"user": {
"id": 1,
"name": "Ed Spencer",
"email": "ed#sencha.com"
}
}
]
}
In the case above the record data is nested an additional level inside the "users" array as each "user" item has additional metadata surrounding it ('id' and 'value' in this case). To parse data out of each "user" item in the JSON above we need to specify the record configuration like this:
reader: {
type : 'json',
root : 'users',
record: 'user'
}
root as a Function
reader: {
type : 'json',
root : function (obj) {
// I can't reproduce your problem
// so you should check in your console collection.id is right
return obj.collection.id
}
}
// Or, we can use dot notation
reader: {
type : 'json',
root : collection[0].tickets.collection
}
There are two ways to solve this problem. After researching extensively, i found two solutions...
SOLUTION 1:
Instead of making a second model, just create one model and create an array field with type as "auto"
Ext.define("myProject.model.ABC", {
extend: "Ext.data.Model",
config: {
idProperty: "id",
fields:[
{name: "id", type: "int" },
{ name: "tickets", convert: function(value, record) {
if(value.collection instanceof Array) {
return value.collection;
} else {
return [value.collection]; // Convert to an Array
}
return value.collection;
}
}
],
}
});
Now you can refer to an array of tickets from records by:
record.get('tickets')
SOLUTION 2:
Create three model instead of two.
Model 1:
hasOne Association with Tickets
Model 2:
hasMany association with Collection
Model 3:
has all the fields of the innermost array
I can give an example if its not clear enough