skip to Main Content

I am trying to filter some data stored in MongoDB using parameters contained in the URL.

My problem is that when the request is sent, the server crashes with the following error:

can't convert from BSON type string to Date

I tried changing the type of the variables to Number hoping that it would fix the problem but I had the same result.

Here you are the code I use to send the request to the server:

async filter(){

        month = this.$refs.month.value;
        year = this.$refs.year.value;

        if(month != "Month" && year != ""){
          const addressToFetch = "/api/budget/" + year + "/" + month;
          console.log("Fetching" + addressToFetch);
          await fetch(addressToFetch).then(response => response.json())
      .then(response => {
          this.expenses = response;
          console.log(response);
      });

        }
    }

This function is executed when an HTML form button is clicked and takes values from two form inputs.

Here you are the code I use to handle the request server-side:

app.get("/api/budget/:year/:month", verify, async (req, res) => {
  const user = req.session.user;

  const year = Number(req.params.year);
  const month = Number(req.params.month);

  console.log("Got " + year + "/" + month);

  const expenses = db
    .collection("expenses")
    .find({
      "users.username": user.username,
      $expr: {
        $and: [
          { $eq: [{ $year: "$date" }, year] },
          { $eq: [{ $month: "$date" }, month] },
        ],
      },
    })
    .toArray();

  console.log(expenses);
  res.json(expenses);
});

I also post the documents stored in the DB for demo purposes:

[
    {
        "_id": "6571eb70320499f416931fd8",
        "id": 2,
        "date": "2021-09-06T00:00:00.000Z",
        "description": "boringday",
        "category": "transport",
        "buyer": "giacomo",
        "cost": 49,
        "users": [
            {
                "username": "paolo",
                "amount": 16.333333333333332
            },
            {
                "username": "giacomo",
                "amount": 16.333333333333332
            },
            {
                "username": "giacomo",
                "amount": 16.333333333333332
            }
        ]
    },
    {
        "_id": "6571eb70320499f416931fe8",
        "id": 18,
        "date": "2019-04-10T00:00:00.000Z",
        "description": "badday",
        "category": "school",
        "buyer": "giacomo",
        "cost": 329,
        "users": [
            {
                "username": "luca",
                "amount": 109.66666666666667
            },
            {
                "username": "luca",
                "amount": 109.66666666666667
            },
            {
                "username": "giacomo",
                "amount": 109.66666666666667
            }
        ]
    },
    {
        "_id": "6571eb70320499f416931feb",
        "id": 21,
        "date": "2021-11-14T00:00:00.000Z",
        "description": "boringexperience",
        "category": "school",
        "buyer": "giacomo",
        "cost": 299,
        "users": [
            {
                "username": "giorgia",
                "amount": 99.66666666666667
            },
            {
                "username": "giacomo",
                "amount": 99.66666666666667
            },
            {
                "username": "giacomo",
                "amount": 99.66666666666667
            }
        ]
    },
    {
        "_id": "6571eb70320499f416931fff",
        "id": 41,
        "date": "2020-04-09T00:00:00.000Z",
        "description": "badtool",
        "category": "sport",
        "buyer": "giacomo",
        "cost": 349,
        "users": [
            {
                "username": "franco",
                "amount": 116.33333333333333
            },
            {
                "username": "franco",
                "amount": 116.33333333333333
            },
            {
                "username": "giacomo",
                "amount": 116.33333333333333
            }
        ]
    }
]

For example, in the case the form is submitted with values year=2021, month=11 I just want the third object to be returned.

Can anyone help me solve the problem?

Thank you in advance for your patience!

2

Answers


  1. your date is in string format saved in the database. You cannot extract the $year and $month from string directly that’s why you are getting the can't convert from BSON type string to Date. You either have to save it as Date type or convert the string to Date type at query time (using $toDate operator) before comparing

    .find({
      "users.username": user.username,
      $expr: {
        $and: [
          { $eq: [{ $year: { $toDate: "$date" } }, year] },
          { $eq: [{ $month: { $toDate: "$date" } }, month] }
        ]
      }
    })
    
    

    playground

    Login or Signup to reply.
  2. If you are encountering the "Cannot convert from BSON type to Date" error in MongoDB, it typically means that there is an attempt to perform an operation that expects a date type, but the data stored in the field is not a valid date or is not in the expected format.

    Here are some steps you can take to troubleshoot and resolve the issue:

    1. Check Data Format:

      • Verify that the data in the field is actually in a date format. MongoDB expects dates to be in the ISODate format. Ensure that your date values are in the correct format.

      Example of valid ISODate:

      ISODate("2023-01-01T00:00:00Z")
      
    2. Identify Incorrect Data:

      • Identify any documents in your collection where the field causing the issue contains data that is not a valid date.
    3. Handle Null or Missing Values:

      • If the field can contain null or missing values, make sure to handle them appropriately. MongoDB may have trouble converting a null or missing value to a date.
    4. Update Data:

      • If you find documents with invalid date data, you may need to update or correct the values in those documents to ensure they conform to the expected date format.

      Example of updating a document:

      db.collection.update(
        { _id: yourDocumentId },
        { $set: { yourDateField: new ISODate("2023-01-01T00:00:00Z") } }
      )
      
    5. Check Aggregation Pipelines:

      • If you are using aggregation pipelines, review your pipeline stages to ensure that they are not producing unexpected data types.
    6. Review Queries:

      • Review your queries to ensure that you are using date comparison operators correctly and that the fields involved contain valid date values.

    If the issue persists, consider providing more details about your data model, the query or operation causing the error, and some example documents from your collection. This additional information can help in providing more specific guidance on resolving the problem.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search