I have the following collection
_id: someid
name: Name 1
status: 0
ref: 152
_id: someid
name: Name 1
status: 0
ref: 152
_id: someid
name: Name 1
status: 3
ref: 152
_id: someid
name: Name 1
status: 0
ref: 273
_id: someid
name: Name 1
status: 3
ref: 679
I'd like to get a result that tells me how many times "ref" appears with the same value where the entry has the status anything except 3. So for example the result I'm looking for is basically
{"152": 2, "273": 1, "679": 0}
Since "ref: 152" appears 2 times while the status is not 3 and "ref: 273" appears 1 times while the status is not 3. I'm using NodeJS, Express, and MongoDB. I've tried to aggregate which to an extent does work however since 679 has 0 the aggregation result omits "679: 0" and that causes the React template to throw an error declaring it undefined. Using aggregation also formats it differently so occasionally the wrong amount is displayed on different rows. I feel if I can access the count by using the reference number as the key it'd be accurate but I can't figure out how to achieve this.
EDIT: I have solved my issue like this:
const count = {}
docs.map((doc) => {
count[doc.ref] = 0
})
docs.map((doc) => {
doc.status < 3 && count[doc.ref]++
})
Which returns exactly what I specified I needed above however I was wondering if there was an even cleaner way to do it?
You can use Array.reduce() function as well.
const countRef = docs.reduce((count, doc) => {
count[doc.ref] = (doc.status !== 3) ? (count[doc.ref] || 0) + 1 : (count[doc.ref] || 0);
return count;
}, {});
// countRef - {"152": 2, "273": 1, "679": 0}
Related
mongo db schema variable
status:{
type: Number,
enum: [0,1,2,3,4,5], //0-NOT ACCEPTED,1-COMPLETED,2-PENDING
default: 0
}
status stored in db like 0 or 1 or 2. status search with user selection is array of datas like
status: {1,2}
how to get the documents which has any one the of the array element. I can't do a static search because array size can change every time
// if(status){
// query = {
// ...query,
// "status": status
// }
// }
console.log(body_status);
if(body_status){
query = {
...query,
"status": {"$in":body_status}
}
}
this works for me.
I don't know if I've understand the question but I think you want something like this:
db.collection.find({
"status": {
"$in": [
1,
2,
4
]
}
})
Example here
Please check if it works as expected or not and in this case update the question with more information.
Or maybe you want something like this:
db.collection.find({
"status": 1
})
Hey guys i need to write a mongodb query to update a document i,e need to increment a field in docuemnt by 1, so for that i am using $inc operation but i am facing trouble in matching the document's key with the data sent by frontend
my db looks like this
_id:ObjectID("5ed4a86126663308549f816b")
title:svsbsbsssf
description:wdwwdwd
category:Object
_id:ObjectID("5ebc1144dde4f2974e209526")
label:World after Covid
category_id:1
url:world-after-covid
image:https://*****/assets/category-1590699874832.jpg
value:1
so this category is an Object and i am getting my category id from frontend, after converting that to ObjectID, i tried to match it like
let doc = await req.db
.collection("webinars")
.updateOne({category._id: categoryID }, { $inc: { listingViews: 1 } });
but the filter inside updateOne gives me error somehow the syntax isnt correct i guess
the error is like
Unexpected token, expected "," (17:26)
15 | let doc = await req.db 16 | .collection("webinars")
17 | .updateOne({category._id: categoryID }, { $inc: { listingViews: 1 } });
There is a syntax error in the updateOne filter object, the nested field path i.e category._id should be a string, something like this
// Notice the quotes around category._id
.updateOne({ "category._id": categoryID }, { $inc: { listingViews: 1 } });
I am trying to get recently inserted record _id and p_id but i do not know how to get the value.Below given my code.This is not working.How to do it?
DB records:
{
_id:5eba58f0e5def333ad4d8c8d,
p_id:"C1",
product_name:"Name",
product_weight:123
},
{
_id:5eba58f0e5def333ad4d8c8e,
p_id:"C2",
product_name:"Name",
product_weight:123
},
{
_id:5eba58f0e5def333ad4d8c8f,
p_id:"C3",
product_name:"Name",
product_weight:123
}
data.controller.js:
var Product = mongoose.model(collectionName);
let latest_id = Product.findOne().sort({ field: 'asc', _id: -1 }).limit(1);
console.log("_id" + val); //output should be 3
let latest_p_id = Product.findOne().sort({ field: 'asc', p_id: -1 }).limit(1);
console.log("p_id" + val); //output should be C3
MongoDB does not natively support incremental auto generated numbers, so your first case, it's not possible if you don't manage your counter separately. You can count the number of documents, but it won't account for deleted documents.
For the second case, you almost got it:
with async/await
const product = await Product.findOne().sort({ p_id: -1 }).limit(1)
console.log(product.p_id) // this will be your desired output
without async/await
Product.findOne().sort({ p_id: -1 }).limit(1).then((product) => {
console.log(product.p_id) // this will be your desired output
})
I'm trying to batch update table users that contains these columns id (primary key) , status (text) , active (numeric).
the array i'm receiving from back-end is something like this:
[
{ id: 33715, status: 'online', active: 10 },
{ id: 39129, status: 'offline', active: 0.1 },
{ id: 36090, status: 'loggedin', active: 24 },
{ id: 34452, status: 'loggedout', active: 1 },
]
active is time in hours. now i want to bulk update this array into users table. as each object represents a row in a table.
I've tried this approach according to this solution Patrick Motard
function bulkUpdate (records) {
var updateQuery = [
'INSERT INTO users (id, status, active) VALUES',
_.map(records, () => '(?)').join(','),
'ON DUPLICATE KEY UPDATE',
'status = VALUES(status),',
'active = VALUES(active)'
].join(' '),
vals = [];
_(records).map(record => {
vals.push(_(record).values());
});
return knex.raw(updateQuery, vals)
.catch(err => {
console.log(err)
});
}
bulkUpdate(response);
but i get this error
error: syntax error at or near "DUPLICATE"
so what i'm missing here. and does anyone by chance have a better solution without using promises or bluebird then do trx.commit , this consumes large cpu and ram. and doesn't do the purpose of update 10,000 row at once
I don't see any ON DUPLICATE KEY UPDATE reference in
https://www.postgresql.org/docs/9.5/sql-insert.html
You could try out ON CONFLICT DO UPDATE SET. Try out first with plain SQL to write a query that seems to work correctly and then it is easy to convert to javascript generated one.
I am using mongoose to perform CRUD operation on MongoDB. This is how my schema looks.
var EmployeeSchema = new Schema({
name: String,
description: {
type: String,
default: 'No description'
},
departments: []
});
Each employee can belong to multiple department. Departments array will look like [1,2,3]. In this case departments.length = 3. If the employee does not belong to any department, the departments.length will be equal to 0.
I need to find all employee where EmployeeSchema.departments.length > 0 & if query return more than 10 records, I need to get only employees having maximum no of departments.
Is it possible to use Mongoose.find() to get the desired result?
Presuming your model is called Employee:
Employee.find({ "departments.0": { "$exists": true } },function(err,docs) {
})
As $exists asks for the 0 index of an array which means it has something in it.
The same applies to a maximum number:
Employee.find({ "departments.9": { "$exists": true } },function(err,docs) {
})
So that needs to have at least 10 entries in the array to match.
Really though you should record the length of the array and update with $inc every time something is added. Then you can do:
Employee.find({ "departmentsLength": { "$gt": 0 } },function(err,docs) {
})
On the "departmentsLength" property you store. That property can be indexed, which makes it much more efficient.
By some reason, selected answer doesn't work as for now. There is the $size operator.
Usage:
collection.find({ field: { $size: 1 } });
Will look for arrays with length 1.
use can using $where like this:
await EmployeeSchema.find( {$where:'this.departments.length>0'} )
If anyone is looking for array length is greater than 1, you can do like below,
db.collection.find({ "arrayField.1" : { $exists: true }})
The above query will check if the array field has value at the first index, it means it has more than 1 items in the array. Note: Array index start from 0.