Was trying to filter an array with another condition to query my MongoDB database
I have tried using the elemMatch
to match exactly with the query, but it not working out.
Here is my code my shipment schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create Schema
const ShipmentSchema = new Schema({
warehouseNo:{
type: String,
ref: 'users.unitNo'
},
packages:[
{
category:{
type: String
},
quantity:{
type: String
},
description:{
type: String
},
trackingno:{
type: String,
},
date:{
type: Date,
default: Date.now
},
length:{
type: Number
},
width:{
type: Number
},
height:{
type: Number
},
weight:{
type: Number
},
fee:{
type: Number,
},
status: {
type: String,
default: "In warehouse"
},
},
],
shippingMode:{
type: String,
},
date:{
type: Date,
default: Date.now
}
});
module.exports = Shipments = mongoose.model('shipments', ShipmentSchema);
Here is my node js.
// @route GET api/user/package
// @desc Get all package
// @access Private
router.get('/package',
passport.authenticate('jwt', { session: false }),
(req, res) => {
const errors = {};
Shipments.findOne({warehouseNo : req.user.unitNo})
.then(shipments => {
if (shipments.packages.length === 0) {
errors.nopackages = 'There are no packages for you yet';
return res.status(404).json(errors);
}
res.json(shipments.packages);
})
});
The code above bring every record in my mongoddb, but if i tried the below, where i ask it to fillter by package status. i got a code crash error
// @route GET api/user/package
// @desc Get all package
// @access Private
router.get('/package',
passport.authenticate('jwt', { session: false }),
(req, res) => {
const errors = {};
Shipments.find({warehouseNo : req.user.unitNo, "packages.status": "In warehouse"})
.then(shipments => {
if (shipments.packages.length === 0) {
errors.nopackages = 'There are no packages for you yet';
return res.status(404).json(errors);
}
res.json(shipments.packages);
})
});
i expect to get something like this
{
"status": "In warehouse",
"date": "2019-09-11T10:19:02.834Z",
"_id": "5d78ca160e47be29e13253b5",
"category": "liquid",
"quantity": "10 pieces",
"description": "garri",
"trackingno": "MHS085533395",
"weight": 123,
"length": 12,
"height": 12,
"width": 13
}
instead i got this
[
{
"status": "Shipped",
"date": "2019-09-11T10:17:46.485Z",
"_id": "5d78c9ca0e47be29e13253b4",
"category": "liquid",
"quantity": "10 pieces",
"description": "garri",
"trackingno": "SDG561920753",
"weight": 123,
"height": 12,
"width": 13
},
{
"status": "In warehouse",
"date": "2019-09-11T10:19:02.834Z",
"_id": "5d78ca160e47be29e13253b5",
"category": "liquid",
"quantity": "10 pieces",
"description": "garri",
"trackingno": "MHS085533395",
"weight": 123,
"length": 12,
"height": 12,
"width": 13
}
]
You should use $elemMatch
inside the key packages
, ie db.getCollection('shipments').find( {warehouseNo: "123"}, { packages: { $elemMatch: { status: "In warehouse" }}})
.
For Example: I have a collection as below:
{
"_id" : 1.0,
"name" : {
"first" : "John",
"last" : "Backus"
},
"birth" : ISODate("1924-12-03T05:00:00.000Z"),
"death" : ISODate("2007-03-17T04:00:00.000Z"),
"contribs" : [
"Fortran",
"ALGOL",
"Backus-Naur Form",
"FP"
],
"awards" : [
{
"award" : "W.W. McDowell Award",
"year" : 1967.0,
"by" : "IEEE Computer Society"
},
{
"award" : "National Medal of Science",
"year" : 1975.0,
"by" : "National Science Foundation"
},
{
"award" : "Turing Award",
"year" : 1977.0,
"by" : "ACM"
},
{
"award" : "Draper Prize",
"year" : 1993.0,
"by" : "National Academy of Engineering"
}
]
}
Using query like this:
db.getCollection('bios').find( {_id: 1.0 }, { awards: { $elemMatch: { year: 1967.0 }}})
Gave me a result:
{ "_id" : 1.0, "awards" : [ { "award" : "WW McDowell Award", "year" : 1967.0, "by" : "IEEE Computer Society" } ] }
Hope this will help you.
You defined warehouseNo as reference from other table. It must be some ID. Please make sure you are comparing the same
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.