I'm starting a project using sails.js and I'ma bit confused about something.
I have a structure like this
[
{
"logins": {
"1": {
"login time": "2016-04-02T11:40:06.731Z"
}
}
"username": "test",
"password": "test",
"createdAt": "2016-04-02T11:40:06.731Z",
"updatedAt": "2016-04-02T11:40:06.731Z",
"id": "56ffaf9692bcf108169ef7c8"
}
]
now when a user logs in again, ideally I want the data to look like this
[
{
"logins": {
"1": {
"login time": "2016-04-01T11:40:06.731Z"
},
"2": {
"login time": "2016-04-02T11:40:06.731Z"
}
}
"username": "test",
"password": "test",
"createdAt": "2016-04-01T11:40:06.731Z",
"updatedAt": "2016-04-01T11:40:06.731Z",
"id": "56ffaf9692bcf108169ef7c8"
}
]
However, I cannot for the live of me figure out how to "update" or "insert" a new row under "logins" for my user.
Creating the first record is fine and so far the best I could come up with is reading the current value for logins into a buffer and then re-inserting all the values.
That seems clumsy. Does anyone know if sails has some built in method to support what I'm trying to achieve?
I would change your 'Logins' argument to array. Than you can use $push while updating. Waterline support only $set operation, so if you want to do that you need to use .native() like that:
Model.native(function(error,collection){
collection.update(
{_id:YOURID}, // where condition
{$push:{logins:new Date()}}, // push new value to array
{}, // options
function(error,result){} // callback
)
})
To see what you can do with native, see Node.js MongoDB Driver API - Collections
Related
I have two different collections for two different type of products. Now, I want to fetch all documents from both collections for a particular user.
I know I can do that with 2 queries for each collection, merging them on the server side and sending the result to the user. Downside of this is that I have to fetch all documents for a user from both collections, which is not good for pagination. That is why I want to do it in one query, so I can leave a pagination logic to MongoDB as well.
Here is the example of collections and expected result:
Products_type_1
[
{
"name": "product_1",
"user": "user_1",
...
},
{
"name": "product_2",
"user": "user_2",
...
}
]
Products_type_2
[
{
"name": "product_3",
"user": "user_1",
...
},
{
"name": "product_4",
"user": "user_2",
...
}
]
The expected result:
[
{
"type": "Products_type_1",
"name": "product_1",
"user": "user_1",
...
},
{
"type": "Products_type_2",
"name": "product_3",
"user": "user_1",
...
}
]
You can use aggregation framework with $unionWith stage:
db.Products_type_1.aggregate([
{
"$match": {
"user": "user_1"
}
},
{
$unionWith: {
coll: "Products_type_2",
pipeline: [
{
"$match": {
"user": "user_1"
}
}
]
}
}
])
Playground: https://mongoplayground.net/p/v0dKCwiKsZU
If you want to use pagination you will need to add sort stage to ensure consistent order of the documents in the result.
Firstly I would query the logic of having a different collection for the different 'product_type_x'. If you had a single collection with an added field...
{ "productType" : 1,
...
},
That way that issue has just been resolved, everything to do with Procts is now accessible in a single collection. Aggregation of your data now becomes simple (by comparison)
I have an Apollo Client that I'm using to request data from a service. I want to use the data I get in response to create a network of nodes and links e.g.
// Response data:
{
"Team": [
{
"name": "Example Team",
"members": [
{ "name": "Bob" },
{ "name": "Alice" }
]
}
]
}
// Network data:
{
"nodes": [
{ "name": "Example Team" }
{ "name": "Bob" },
{ "name": "Alice" }
],
"links": [
{ "source": "Example Team", "target": "Bob" },
{ "source": "Example Team", "target": "Alice" }
]
}
Historically, before using GraphQL, I would have used Redux to store the munged API response in state and read from there.
Is it appropriate to take a GraphQL result from Apollo and immediately save it back to Apollo local state in a different form so it can be queried by components in that format?
The main problem I foresee is that I think I'd have to query to check if the data I want exists in local state, then make another query if it didn't. In a Redux-world this would be wrapped up inside my store which would then only make the request off to the API if it didn't have the data it needed which 'feels' much cleaner.
In my case this could be solved using Afterware in Apollo Client, see this answer for more information.
It would allow me to munge the returned data into the form I need, and return it in the response alongside the original data.
I would like to get a modified response object. For example I dont know how to get the user object without the roles.
The default response is:
{
"id": 6,
"username": "username",
"email": "user#email.com",
"provider": "local",
"confirmed": true,
"blocked": false,
"role": {
"id": 2,
"name": "Authenticated",
"description": "Default role given to authenticated user.",
"type": "authenticated"
}
}
Now I want to get the same response without the role attribute.
{
"id": 6,
"username": "username",
"email": "user#email.com",
"provider": "local",
"confirmed": true,
"blocked": false
}
Currently you cannot do this in the Rest API unless you change the UserController provided by permissions plugin, which is not recommended.
What you can do then is to use the GraphQL plugin provided by Strapi, so you can query only the fields you need on client side.
The docs about how to use GraphQL plugin are here.
For anyone still struggling with this problem:
The latest versions of strapi do support custom queries, you can pass an array containing all the names of relations you wish to populate (only relations!).
If you don't want to populate any relationships, you can keep it empty, your controller would then look something like this:
module.exports = {
UserWithoutRoles: ctx => {
return strapi.query('user').findOne({ id: ctx.params.id }, ['']);
}
}
If you do wish to populate it, it would be like this:
module.exports = {
UserWithoutRoles: ctx => {
return strapi.query('user').findOne({ id: ctx.params.id }, ['role']);
}
}
Also see:
[https://strapi.io/documentation/3.0.0-beta.x/concepts/queries.html#api-reference][1]
Upon viewing the Mongo Count docs, it showed the following code :
// Peform a partial account where b=1
collection.count({b:1}, function(err, count) {
where it count every document that has b:1. Those documents can look something like this
{
a:1,
b:1,
c:1
}
How can I find the partial account on a more in-depth level. For example consider the following document. How can I count every document that contains
"Name": "LOG-11-05-SH-O1.mp4" ?
"display": {
"0": {
"Name": "LOG-11-05-SH-O1.mp4",
"Type": "Startup",
"Count": "2",
"Detail": {
"0": {
"Start": "2013-01-20,11:32:22",
"End": "2013-01-20,11:32:30"
},
"1": {
"Start": "2013-01-20,11:32:22",
"End": "2013-01-20,11:32:30"
}
}
},
"1": { ....
I know that "display.0.Name" : "LOG-11-05-SH-O1.mp4" will count everytime "LOG-11-05-SH-O1.mp4" appears under display 0, but sometimes the number may change. For example, next time time "LOG-11-05-SH-O1.mp4" might be under display 1. Thus is there a way to perform a count on only "LOG-11-05-SH-O1.mp4" or perhaps ignore the middle number?
See my comments on your question, but I don't see a way to do this without using an array instead of an object for the value of display. If it is an array, this becomes trivial.
Suppose your data looked like this:
"display": {[
{
"Name": "LOG-11-05-SH-O1.mp4",
"Type": "Startup",
"Count": "2",
"Detail": {
"0": {
"Start": "2013-01-20,11:32:22",
"End": "2013-01-20,11:32:30"
},
"1": {
"Start": "2013-01-20,11:32:22",
"End": "2013-01-20,11:32:30"
}
}
, { ....}
]}
Then you query would just be:
db.foos.count({"display": {$elemMatch: { "Name" : "LOG-11-05-SH-O1.mp4"}}})
Here is the relevant MongoDB page on $elemMatch: http://docs.mongodb.org/manual/reference/operator/projection/elemMatch/.
If you must keep the object schema, then you can grab all the records and do the count on the app side and not in MongoDB.
If someone else knows a way to pull this off without the array, I'm happy to receive a downvote and then just remove what would then be an incorrect answer.
I feel kind of silly not realizing this at first. The answer is quite simple:
"display.Name": "LOG-11-05-SH-O1.mp4"
This will find all entries under display that has that following name.
I am getting a following JSON(/users.json) which contains users:
[
[
{ "id": "43343", "project_id": "1", "username": "Amy" }
{ "id": "34244", "project_id": "1", "username": "Tommy" }
],
[
{ "id": "76575", "project_id": "2", "username": "Izzy" }
{ "id": "13322", "project_id": "2", "username": "Sam" }
],
{ "id": "09983", "project_id": "3", "username": "Max" }
]
When project has one user I get one user hash which is not in array.
I would like to build a Backbone collection with all users. How to do that?
You provide an array of arrays of users. So to fetch all users in the init method, you can give it data but as an array of users, i.e. you will flatten this original array of arrays once with underscore flatten method :
data = _(data).flatten(true);
Then the collection constructor will natively understand your json array.
But maybe you already do this transformation in the fetching method and this is not the problem you are facing..
If you have defined a collection (say userCollection) with a user model you should be able to simply do something like this:
var col;
$.getJSON("/users.json", function(data) {
col = new userCollection(data);
});
This would more likely be done in the fetch function of the collection, but the principle here is that you can pass an array of objects to a collection and it will marshal all from json to backbone models.