SO i try to query data using mongodb on ES6 using this query:
const { title = "", date1 = "", user = "", date2 = "" } = req.query;
const formIds = req.params.formId;
let forms = "";
if (date2 === "undefined") {
console.log(date1, date2, formIds);
}
const form = await Form.findOne({
_id: req.params.formId,
});
if (!form) {
throw { code: 404, message: "FORM_NOT_FOUND" };
}
console.log(form.id);
if (date2 === "undefined") {
forms = await Answer.aggregate([
{
$match: {
$and: [{ date: date1 }, { formId: o_id }],
},
},
{
$group: {
_id: "$title",
title: {
$first: "$title",
},
answer: {
$push: {
username: "$username",
date: "$date",
formId: "$formId",
answers: "$answer",
},
},
},
},
]);
}
but because it using ObjectId on Mongo.., i cannot return the value even though it has the value on the database with format like this:
{
"_id": {
"$oid": "636242358721c33778b16e0f"
},
"userId": {
"$oid": "6355d841bf2fc81f76edfbd9"
},
"formId": {
"$oid": "6361c5aaf7a02c177ebebb27"
},
"title": "Untitled Form",
"username": "jansenstan2410#gmail.com",
"date": "2022-11-02",
"answer": {
"Test": [
"New Option"
],
"Email": "john#nabatisnack.com",
"Dropdown": "New Option",
"Radio": "3",
"Date": "2022-11-01T00:00:00.000Z",
"Time": "17:25"
}
}
can someone tell me where did i do wrong here?i try to find answer all the answer using require while in ES6 i use mongoose
Related
I'm a beginner trying to create an API using express ang mongodb and this is my first time posting a question here, so forgive me if my question sounds stupid.
I have this data:
Restaurants
[
{
"_id": "630c0d5e82d52d0852d34b11",
"name": "Restaurant 1",
"type": "Fine Dining",
"cuisine": "Korean",
},
{
"_id": "630c0d5e82d52d0852d34b12",
"name": "Restaurant 2",
"type": "Fine Dining",
"cuisine": "International",
},
{
"_id": "630c0d5e82d52d0852d34b13",
"name": "Restaurant 3",
"type": "Casual Dining",
"cuisine": "Korean",
},
{
"_id": "630c0d5e82d52d0852d34b14",
"name": "Restaurant 4",
"type": "Casual Dining",
"cuisine": "International",
},
...
]
so what I want to achieve is when I create a GET request to this API endpoint http://localhost:8000/api/v1/restaurants/stats is this:
{
"status": "success",
"data": {
"cuisines": [
{
"_id": "Korean",
"restaurants": ["630c0d5e82d52d0852d34b11", "630c0d5e82d52d0852d34b13"],
"quantity": 2
},
{
"_id": "International",
"restaurants": ["630c0d5e82d52d0852d34b12", "630c0d5e82d52d0852d34b14"],
"quantity": 2
}
],
"type": [
{
"_id": "Casual Dining",
"restaurants": ["630c0d5e82d52d0852d34b14", "630c0d5e82d52d0852d34b13"],
"quantity": 2
},
{
"_id": "Fine Dining",
"restaurants": ["630c0d5e82d52d0852d34b11", "630c0d5e82d52d0852d34b12"],
"quantity": 2
}
]
}
}
This is what I have tried so far
restaurantController.js
...
exports.getRestaurantStats = async (req, res) => {
const cuisines = await Restaurant.aggregate([
{
$group: {
_id: '$cuisine',
restaurants: { $push: '$_id' },
quantity: { $sum: 1 },
}
},
]);
res.status(200).json({
status: 'success',
data: {
cuisines,
},
});
};
...
restaurantRoutes.js
...
router.route('/stats').get(restaurantController.getRestaurantStats);
...
The result for calling this endpoint http://localhost:8000/api/v1/restaurants/stats
{
"status": "success",
"data": {
"cuisines": [
{
"_id": "Korean",
"restaurants": ["630c0d5e82d52d0852d34b11", "630c0d5e82d52d0852d34b13"],
"quantity": 2
},
{
"_id": "International",
"restaurants": ["630c0d5e82d52d0852d34b12", "630c0d5e82d52d0852d34b14"],
"quantity": 2
}
]
}
But when I add this another group by
...
$group: {
_id: '$type',
restaurants: { $push: '$_id' },
quantity: { $sum: 1 },
}
...
to restaurantController.js
...
exports.getRestaurantStats = async (req, res) => {
const cuisines = await Restaurant.aggregate([
{
$group: {
_id: '$cuisine',
restaurants: { $push: '$_id' },
quantity: { $sum: 1 },
},
$group: {
_id: '$type',
restaurants: { $push: '$_id' },
quantity: { $sum: 1 },
}
},
]);
res.status(200).json({
status: 'success',
data: {
cuisines,
},
});
};
...
the result is different. Its seems like it overwrote the first group by in the pipeline.
varyantalt Model:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const varyantaltSchema = new Schema({
_id: {
type: Schema.ObjectId
},
varyantid: {
type: String
},
altvaryantname: {
type: String
},
createdAt: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model("varyantalt", varyantaltSchema, "varyantalt");
varyant model:
const varyantSchema = new Schema({
_id: {
type: Schema.ObjectId
},
stokid: {
type: Schema.ObjectId
},
varyantname: {
type: String
},
createdAt: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model("varyant", varyantSchema, "varyant");
varyant collection:
{
"_id": ObjectId("5e32286c34fb7322bdd566ed"),
"stokid": ObjectId("5e28b4a2a1d9692b29a65b24"),
"varyantname": "RENK"
}
altvaryant collection:
{
"_id": ObjectId("5e3228df34fb7322bdd566f5"),
"varyantid": "5e32286c34fb7322bdd566ed",
"altvaryantname": "KIRMIZI",
"vars": [
{
"_id": ObjectId("5e35b1e410fce83f3370cd0a"),
"images": {
"imageurl": "http://",
"_id": ObjectId("5e35b1e410fce83f3370cd0b"),
"filename": "5320_7d93",
"path": "https://res",
"publicid": "panel"
}
}
]
},
{
"_id": ObjectId("5e3359e6fa4c5e4bd9112fb6"),
"varyantid": "5e32286c34fb7322bdd566ed",
"altvaryantname": "SARI",
"vars": [
{
"_id": ObjectId("5e35b1f610fce83f3370cd0d"),
"images": {
"imageurl": "http://",
"_id": ObjectId("5e35b1f610fce83f3370cd0e"),
"filename": "veli-fidan-1LT-2-450x450",
"path": "https://",
"publicid": "panel"
}
}
]
},
{
"_id": ObjectId("5e335b64fa4c5e4bd9112fc9"),
"varyantid": "5e32286c34fb7322bdd566ed",
"altvaryantname": "YEŞİL",
"vars": [
{
"_id": ObjectId("5e35b20010fce83f3370cd10"),
"images": {
"imageurl": "http://",
"_id": ObjectId("5e35b20010fce83f3370cd11"),
"filename": "maxresdefault-29-450x450",
"path": "https://",
"publicid": ""
}
}
]
}
Query:
varyant
.aggregate([
{
$match: {
stokid: mongoose.Types.ObjectId("5e28b4a2a1d9692b29a65b24")
}
},
{
$lookup: {
from: "varyantalt",
localField: "_id",
foreignField: "varyantid",
as: "vars"
}
},
{ $unwind: "$vars" }
])
.exec((err, locations) => {
if (err) throw err;
console.log("res::", locations);
});
I am trying to get results with $aggregate and $lookup query with mongoose
Why is my query returning empty? I couldn't find the problem.
Under $lookup operator from: 'varyantalt' I do not understand exactly whether it takes a blank value. Thanks in advance for your help.
In your varyantaltSchema schema, varyantid is defined as String, but it must be Schema.ObjectId.
They must be same because $lookup performs an equality match on the foreignField to the localField from the input documents
If you save your varyandid as Object id aggregate will work.
I have following schemas.
First: AdditionalFieldSchema
const AdditionalFieldSchema = new Schema({
names: [
{
type: Schema.Types.ObjectId,
ref: "multiLanguageContent",
required: true
}
],
...
});
Second: MultiLanguageContentSchema
const MultiLanguageContentSchema = new Schema({
value: {
type: String,
required: true
},
...
});
and I have the following mongoose aggregate query.
The goal is to fetch every employees with their additionalField attached.
const employees = await Employee.aggregate([
{
$match: {
status: "active",
$nor: [
{ email: "blablabla" },
{ email: "blobloblo" }
]
}
},
{
$lookup: {
from: AdditionalField.collection.name,
let: { af_id: "$_id" },
pipeline: [{
$match: {
$expr: {
$and: [
{ $eq: ["$ownership", "$$af_id"] },
{ $eq: ["$status", "active"] },
{ $eq: ["$functionalType", "blablabla"] }
]
}
}
}],
as: "afs"
}
},
{ $unwind: "$afs" },
{ $unwind: "$afs.names" },
{
$group: {
_id: "$_id",
email: { $first: "$email" },
afs: {
$push: {
value: "$afs.value",
names: "$afs.names"
}
}
}
}
]);
The query I run to test this aggregate function.
query TestQuery {
testQuery
{
email
afs {
names {
value
}
value
}
}
}
The result I have.
"data": {
"testQuery": [
{
"email": "blablabla#test.com"
"afs": [
{
"names": [
{
"value": "Name 1"
}
],
"value": "Value 1"
},
{
"names": [
{
"value": "Name 2"
}
],
"value": "Value 2"
},
...
]
},
...
Result is good, I have data I want.
But I would like to have a result like this below
"data": {
"testQuery": [
{
"email": "blablabla#test.com",
"afs": [
{
"names": "Name 1",
"value": "Value 1"
},
{
"names": "Name 2",
"value": "Value 2"
},
...
]
},
...
It seems like { $unwind: "$afs.names" }, is not working.
Any ideas ?
Thanks, Flo
I'm trying to select only some fields in document while also using $elemmatch. It turned out the field selection is getting ignored.
Given a document like this:
{
"author": "Robin Sharma",
"data": [
{
"translation": "en",
"content": "foo",
"unwanted_content": "huyu1",
},
{
"translation": "id",
"content": "bar",
"unwanted_content": "huyu2",
{
],
}
I'm using find() with this projection config:
const projection = {
author: 1,
data: {
$elemMatch: {
translation: "en"
},
},
}
Expected
{
"author": "Robin Sharma",
"data": [
{
"translation": "en",
"content": "foo"
},
],
}
Actual
{
"author": "Robin Sharma",
"data": [
{
"translation": "en",
"content": "foo",
"unwanted_content": "huyu1",
},
],
}
I'm still not sure how to get rid of the "unwanted_content" field.
You can achieve your required result using aggregate as:
db.collection.aggregate([
{
$unwind: "$data"
},
{
$match: {
"data.translation": "en"
}
},
{
$group: {
_id: "$author",
data: {
$push: {
translation: "$data.translation",
content: "$data.content"
}
}
}
}
])
I think you can do something like this to get only selected fields from subdocument.
db.collection.find({"data.translation": "en"},{author: 1, "data.content": 1, "data.translation": 1})
I'm trying to count the number of votes per question for the following schema.
[
{
"_id": "564b9e13583087872176dbd2",
"question": "fav NFL team",
"choices": [
{
"text": "St. Louis Rams",
"_id": "564b9e13583087872176dbd7",
"votes": [
{
"ip": "::ffff:192.168.15.130",
"_id": "564b9e30583087872176dbd8"
},
{
"ip": "::ffff:192.168.1.1",
"_id": "564bb355e4e1b7200da92668"
}
]
},
{
"text": "Oakland Raiders",
"_id": "564b9e13583087872176dbd6",
"votes": [
{
"ip": "::ffff:192.168.1.135",
"_id": "564bb273e4e1b7200da92667"
}
]
},
{
"text": "Denver Broncos",
"_id": "564b9e13583087872176dbd5",
"votes": []
},
{
"text": "Kansas City Chiefs",
"_id": "564b9e13583087872176dbd4",
"votes": [
{
"ip": "::ffff:192.168.1.100",
"_id": "564bab48e4e1b7200da92666"
}
]
},
{
"text": "Detroit Lions",
"_id": "564b9e13583087872176dbd3",
"votes": [
{
"ip": "::ffff:192.168.15.1",
"_id": "564b9f41583087872176dbd9"
}
]
}
]
}
]
I'm assuming I am going to have to use aggregate and sum.
I was able to get the count for the choices array, but I'm not sure how to go deeper.
db.polls.aggregate([{$unwind: '$choices'}, {$group:{_id:'$_id', 'sum':{$sum:1}}}])
The vote count for "fav NFL team" would be 5.
Also, for reference here is my mongoose code that generated the schema
var mongoose = require('mongoose');
var voteSchema = new mongoose.Schema({
ip: 'String'
});
var choiceSchema = new mongoose.Schema({
text: String,
votes: [voteSchema]
});
exports.PollSchema = new mongoose.Schema({
question: {
type: String,
required: true
},
choices: [choiceSchema]
});
I figured out how to do it in mango, I needed another unwind.
db.polls.aggregate([
{$unwind: '$choices'},
{$unwind:'$choices.votes'},
{$group:{
_id:'$_id',
'sum':{
$sum:1
}
}}
])
And here it is in mongoose
Poll.aggregate([
{$unwind: '$choices'},
{$unwind: '$choices.votes'},
{$group:{
_id: '$_id',
'sum': {
$sum:1
}
}}
], function(err, result) {
if (err) {
console.log(err);
}
res.json(result);
});