Destructuring a Sequelize query - node.js

I'm having trouble deconstructing a simple Sequelize query.
const character = await Character.findAll({
order: ['created_at'],
attributes: ['id', 'name', 'created_at'],
});
I want to access the "created_at" of the list, but I try to
const { created_at } = character;
But it returns undefined.
I need to subtract the current date from the created_at date.
Could someone tell me what I'm doing wrong or how could I do it?
I have Moment.js installed if needed.
Query return
{ "id": 10, "name": "John Doe", "created_at": "2020-08-08T20:52:06.262Z" },
{ "id": 11, "name": "Mary Jane", "created_at": "2020-08-08T21:01:49.562Z" },
{ "id": 12, "name": "Clark Kent", "created_at": "2020-08-08T21:02:51.948Z" }
]

In you case you are trying to do a destructuring from an array. But it only works in an object.
To it to work you should use an index.
Something like:
const { created_at } = character[0];
Notice that it will only destruct the position zero from your results contained in the character array. If you do not would like the position zero you should use another function to choose the desired result.

Related

Mongodb update all the documents with unique id

I have collection with name products with almost 100k documents. I want to introduce a new key called secondaryKey with unique value uuid in all the documents.
I do this using nodejs.
Problem I am facing:-
When I try the below query,
db.collection('products').updateMany({},{"$set":{secondaryKey: uuid()}});
Here it updates all the documents with same uuid value,
I try with loop to update document one by one,but here issues is I don't have filter value in updateOne because I want to update all the documents.
Can anyone please help me here.
Thanks :)
If you are using MongoDB version >= 4.4 You can try this:
db.products.updateMany(
{},
[
{
$set: {
secondaryKey: {
$function: {
body: function() {
return UUID().toString().split('"')[1];
},
args: [],
lang: "js"
}
}
}
}
]
);
Output
[
{
"_id": ObjectId("..."),
"secondaryKey": "f41b15b7-a0c5-43ed-9d15-69dbafc0ed29"
},
{
"_id": ObjectId("..."),
"secondaryKey": "50ae7248-a92e-4b10-be7d-126b8083ff64"
},
{
"_id": ObjectId("..."),
"secondaryKey": "fa778a1a-371b-422a-b73f-8bcff865ad8e"
}
]
Since it's not the same value you want to put in each document you have to use the loop.
In your loop, you have to update the current document of the iteration. So you have to filter with the _id in the updateOne
The above reply didn't work for me. Plus, it compromises security when you enable javascript on your database (see here $function and javascript enabling on database). The best way is to not overload your server, do your work on local as below:
const { nanoid, customAlphabet } = require('nanoid')
async function asdf() {
const movies = await client.db("localhost").collection("productpost");
var result2 = []
let result = await movies.find({}).toArray()
result.forEach(element => {
const nanoid = customAlphabet('1234567890', 10)
console.log(element.price)
element.price = 4
element.id = nanoid()
result2.push(element)
});
console.log("out reult2", result2)
await movies.deleteMany({})
await movies.insertMany(result2)
})
It will delete any objects on your collections and update with the new ones. Using nanoid as uniqueids.
This is the database object array after adding unique id:
{ "_id": { "$oid": "334a98519a20b05c20574dd1" }, "attach": "[\"http://localhost:8000/be/images/2022/4/bitfinicon.png\"]", "title": "jkn jnjn", "description": "jnjn", "price": 4, "color": "After viewing I am 48.73025772956596% more satisfied with life.", "trademark": "", "category": "[]", "productstate": "Published", "createdat": { "$date": "2022-04-03T17:40:54.743Z" }, "language": "en"}
P.S: Please backup your collection before doing this or filter the array on your needs for not going through all collection.

How to orderby/sort incoming data from Firebase

I'm working on a firebase and node.js Express project which is basically an ordering system.
I want to sort my incoming order by time. I've tried using the Orderby() function that firebase provide but it still messes up the order in the json output.
It seems that this should work and i didn't have to sort it in afterwards on my frontend
This is my get route for the firebase
// route for database
router.get("/orderslist", (req, res) => {
let orders = []
let number_of_orders
// Getting the snapshot of the order collection
db.collection('orders').orderBy('time').get().then( productSnapshot => {
number_of_orders = productSnapshot.size
// iterating over the order snapshot
productSnapshot.forEach(orderDoc => {
// creating an order object and assigning the ID and the rest of the information from the database
var order = {
id: orderDoc.id,
customer_name: orderDoc.data().customer_name,
date: orderDoc.data().date,
comments: orderDoc.data().comments,
time: orderDoc.data().time,
total: orderDoc.data().total,
order_status: orderDoc.data().order_status,
products: []
}
// using the id, to get the products from the subcollection
db.collection('orders/' + order.id + '/products').get().then( productSnapshot => {
// iterating over the product snapshot
productSnapshot.forEach(productDoc => {
// creating a product object
var product = {
name: productDoc.data().name,
price: productDoc.data().price
}
// then we push the product object to the list of products in the order object
order.products.push(product)
});
// we are finished iterating over the productsnapshot and now we can push it to the orders list
orders.push(order)
// checks if the list is filled with everything from the database
if(orders.length == number_of_orders){
return res.json(orders)
}
});
});
});
});
This is the data in json
[
{
"id": "xWmlB9fHD4rw8Di75llp",
"customer_name": "Emil",
"date": "07/05-2020",
"comments": "without sugar",
"time": "a",
"total": 40,
"order_status": true,
"products": [
{
"name": "Latte",
"price": 40
}
]
},
{
"id": "GWJoxe0DVFDWfi2AW6jS",
"customer_name": "test",
"date": "222222",
"comments": "",
"time": "f",
"total": 10,
"order_status": false,
"products": [
{}
]
},
{
"id": "ggYSVKA1i0U8khIpeud4",
"customer_name": "Oliver",
"date": "01/05-2020",
"comments": "order to be packed neatly because im on a bike",
"time": "d",
"total": 38,
"order_status": false,
"products": [
{
"name": "Latte Macchiato",
"price": 38
}
]
}
]
I recommend that you create a proper Firestore timestamp field to be used as a reference not the string field you have called "time".
With that being said, knowing Firestore timestamps can be tricky, here's how you can use them.
When you get timestamps from Firestore they are of the following type:
To convert this into a normal timestamp you can use the .toDate() function.
For example, for a document like the following:
We can use something like:
db.collection('[COLLECTION]').doc('[DOCUMENT]').get().then(function(doc) {
console.log(doc.data().[FIELD].toDate());
});
and the output will be like:
2019-12-16T16:27:33.031Z
Now to process that timestamp further, you can convert it into a string and use regex to modify it according to your needs.
For example: (I'm using Node.js here)
db.collection('[COLLECTION]').doc('[DOCUMENT]').get().then(function(doc) {
var stringified = doc.data().[FIELD].toDate().toISOString();
//console.log(stringified);
var split1 = stringified.split('T');
var date = split1[0].replace(/\-/g, ' ');
console.log(date);
var time = split1[1].split('.');
console.log(time[0]);
});
Will give you an output like this:
Now you can use the orderby approach on the query itself or once you fetch them in your frontend.
An example orderby is the following:
db.collection('[COLLECTION]')
.orderBy("timeStamp", Query.Direction.ASCENDING)
However, if you plan to keep using the string type you have there (not recommended), you will have to convert that string to a numeric value (possible ASCII) to be able to filter on that properly as a time object.

MongoDb match an unknown number of different values

I am trying to extract some data out of a MongoDB.
My DB looks something like this;
{
"name": "A",
"address": "London Road",
"values": [{"id": 1234, "name":"ABCD"},{"id": 6784, "name":"test"}]
}
{
"name": "B",
"address": "South Road",
"values": [{"id": 4327, "name":"guest"},{"id": 6743, "name":"demo"}]
}
{
"name": "C",
"address": "North Road",
"values": [{"id": 1234, "name":"ABCD"}]
}
I am trying to extract data based on the values id key.
So if I match 1234 to values id i'll return Elements A and C - I am able to do this.
The values I want to match may change, they could be 1234 or 6743 - returning Elements A, B and C.
I have created the below $or to handle this however the number of values to match varies, so the number of $or functions should change dependent on the number of values to match.
How do I create a query that allows me to match an unknown number of different values? - Maybe a loop?
Thanks in advance. I have search SO and the net and haven't had much success!
const orders = await findr.find({
$or: [{
values: {
$elemMatch: {
id: "1234",
}
}
},
{
values: {
$elemMatch: {
id: "6743",
}
}
}
]
}).toArray()
You can write the query using $in: {"values.id": { $in: ["123", "456"] }}
$elemMatch isn't necessary because you're only specifying a single criterion.

Mongoose how to find specific value

After a lot of reading, I am stuck.
the code I posted here, is the implementation of a store database I am trying to make.
in every store, we have some fields. I am interested in doing something with the items array, that contains JSON variables.
I want to filter the items through three filters, firstly by the store ID, secondly by the category ID, and the last filter will be the semi category ID.
I want to send the data from the front end, meaning I supply STOREID, the CategoryID, and the SemiCategoryID.
after receiving the data at the back end side, I am expecting to receive only the relevant items according to the data supplied by the front end.
{
"_id": {
"$oid": "5a1844b5685cb50a38adf5bb" --> **ID of the STORE**
},
"name": "ACE",
"user_id": "59e4c41105d1f6227c1771ea",
"imageURL": "none",
"rating": 5,
"items": [
{
"name": "NirCohen",
"categoryID": "5a0c2d292235680012bd12c9",
"semiCatID": "5a0c2d5a2235680012bd12ca",
"_id": {
"$oid": "5a1958181cd8a208882a80f9"
}
},
{
"name": "he",
"categoryID": "5a0c2d292235680012bd12c9",
"semiCatID": "5a0c2d5a2235680012bd12ca",
"_id": {
"$oid": "5a1973c40e561e08b8aaf2b2"
}
},
{
"name": "a",
"categoryID": "5a0c2d292235680012bd12c9",
"semiCatID": "5a0c2d5a2235680012bd12ca",
"_id": {
"$oid": "5a197439bc1310314c4c583b"
}
},
{
"name": "aaa",
"categoryID": "5a0c2d292235680012bd12c9",
"semiCatID": "5a0c2d5a2235680012bd12ca",
"_id": {
"$oid": "5a197474558a921bb043317b"
}
},
],
"__v": 9
}
and I want the Backend to return the filtered items according to the query.
The problem is, I am not managing to get the CORRECT query.
your help will be much appreciated,
thank you in advance.
If I understand you correctly, you are doing something like this:
Store.find({}).then(..);
If you only want to find the stores where categoryID is equal to the variable myCategory, you could filter them out by using:
Store.find({semiCatID: myCategory}).then(..);
Please let me know if this is not what you are after, then we can keep trying to figure this out together.
EDIT: So you are sending the variables StoreID, CategoryID and SemiCategoryID from the frontend. Receive them in the backend, and want to filter your database collection matching all three fields?
If so.. then I think all you have to do is change your current query:
store.findOne({ _id: req.body.userID }, (err, store) => { console.log(store); });
To something like:
store.findOne({
_id: req.body.userID,
storeID: req.body.StoreID,
categoryID: req.body.CategoryID,
semiCategoryID: req.body.SemiCategoryID
}, (err, store) => { console.log(store); });
This way, the objects you get back from mongo must match all four criterias given from the frontend.
As far as I Understood your question here is my answer to it you can use findById
Store.findById({//store id}).then(..);
or
Store.findOne({_id:ObjectID(storeID)}).then(..);

mongoose findOne query with multiple conditions and "$gt" not returning proper results

I am stumped by mongoose. I am trying to find a record that matches on both instanceId and currentQuantity. I can see the records in the database, and I know that currentQuantity is numeric not character. But these records are not being found by my query.
I have tried this:
titleRecords.findOne({"titleByDate.instanceId": 100156
})
Result: returns the queries, but doesn't include the second condition which I need. So I tried this:
titleRecords.findOne({"titleByDate.instanceId": 100156
, "titleByDate.currentQuantity": {"$gt": 0}
})
Result: doesn't return the records I'm looking for (returns no records at all)
And I have tried this with extra brackets:
titleRecords.findOne({{"titleByDate.instanceId": 100156
, "titleByDate.currentQuantity": {"$gt": 0}
}})
Result: I get an error that the first { is unexpected
And I have tried this:
titleRecords.findOne({"titleByDate.instanceId": 100156
, "titleByDate.currentQuantity": {$gt: 0}
})
Result: doesn't return any records. I think quotes are required around "$gt" but honestly I'm so confused by mongoose syntax and can't for the life of me find any documentation of how to do this on mongoosejs.com
Per request, here are three sample records. The first query above returns the middle record - none of the others return anything. I apologize if this is not the right format to share the data in - please let me know if there is a better way
{
"_id": {
"$oid": "59936"
},
"titleByDate": {
"currentQuantity": 4,
"title": "ABC",
"instanceId": 150351
},
"__v": 0
},
{
"_id": {
"$oid": "54936"
},
"titleByDate": {
"currentQuantity": 2,
"title": "QPR",
"instanceId": 100156
},
"__v": 0
},
{
"_id": {
"$oid": "51936"
},
"titleByDate": {
"currentQuantity": 0,
"title": "QQQ",
"instanceId": 143159
},
"__v": 0
}
And my model statement:
var mongoose = require('mongoose');
mongoose.Promise = global.Promise;
// define the schema for a play
var titleListingSchema = mongoose.Schema({
title : {
titleId : Number,
title : String,
},
titleByDate :{
instanceId : Number,
title :String,
currentQuantity: Number
}
});
module.exports = mongoose.model('titleListing', titleListingSchema);

Resources