0

I have a document thats selected by a timestamp field. And in that document is an array with an ID Value. I want to filter first for the timestamp field thats in a Date range, and then filter for the subdocument in the array with the right ID.

I am using MEAN stack and have a route with url parameter :start and .demo_id:

my aggregation query looks like:

exports.getProdukt_start_demo_id = function(req,res) {
    console.log(req.params.start),
    console.log(req.params.demo_id),
    //db.produkts.aggregate({$match:{"von":{$gte: ISODate("2018-06-07T15:17:04")}}}).pretty()
    Produkt.aggregate([
        {
            '$match' : { 'von' : { '$gte' : new Date(req.params.start)} }
        },      
        {
            $addFields: {
                "DemonstratorWerte": {
                    $filter: {
                        input: "$DemonstratorWerte",
                        as: "doc",
                        cond: { //$eq: ["$$doc.Demonstrator", req.params.demo_id ] }
                            $and: [
                                { $gte: [ "$$doc.Demonstrator", req.params.demo_id ] },
                                { $lte: [ "$$doc.Demonstrator", req.params.demo_id ] }
                            ]
                        }
                    }

             }
        }
    }

        ]).exec(function(err, prod) {
            if (err) {
                    console.log(err);
                }

            else {
                console.log(prod)
                console.log(prod.values)
                console.log(typeof prod)
                for (let doc of prod) {
                    console.log(doc["von"]);
                    console.log(doc["DemonstratorWerte"]["Demonstrator"])
                }
                res.json(prod);
            }
        })//.then((res) => res.json())
    }

As response object, I get correctly selected documents based on the "von" timestamp. But the filtering by array Subdocument ID returns me an empty array "DemonstratorWerte": [] in the response:

[{"_id":4,"Name":"MProdukt","Beschreibung":"Nutzen Sie diese Produkt","von":"2018-06-07T14:17:03.391Z","bis":"2018-06-14T14:17:03.391Z","Erstellungszeitpunkt":"2018-06-14T14:17:03.391Z","DemonstratorWerte":[],"ProduktStorniertGesamt":{"Timestamp":"2018-06-07T01:41:20.391Z","Status":true}]
MMMM
  • 3,320
  • 8
  • 43
  • 80
  • Show a source document that people can actually reproduce from. Take a look around you and realize that we are not sitting at your desk beside you and of course cannot see what your data looks like unless you show us. – Neil Lunn Jun 08 '18 at 10:40
  • 1
    That's the tip for future questions. For here you need to cast `ObjectId` values manually. This does not happen in aggregation pipelines in the automatic way it happens in a `find()` or other operation. Modern mongoose releases you can import with `const { Types: { ObjectId } } = require('mongoose')` – Neil Lunn Jun 08 '18 at 10:44
  • demo_id or Demonstrator-id is actually a Long Number from "mongoose-long". But thanks for the tip, actually a convert to Number(req.params.id) in the condition did the trick :) – MMMM Jun 08 '18 at 11:05
  • Same deal anyway. "Casting". The most common is ObjectId and you did not give a schema. Also `+req.params.id` is a much shorter way to go to a number. – Neil Lunn Jun 08 '18 at 11:07

0 Answers0