Query to retrieve the most recent message from all users and a specific user resulting in an empty array

My goal is to retrieve all messages exchanged between User A and any other user.

This is my schema structure:

const MostRecentMessageSchema = new Schema({
  to: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "user"
  },
  from: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "user"
  },
  conversation: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "conversation"
  },
  date: {
    type: Date,
    default: Date.now
  }
});

Here is the query I have been using:

    await MostRecentMessages.aggregate(
      [
        {
          $match: {
            $or: [
              {
                to: id
              },
              {
                from: id
              }
            ]
          }
        },
        { $sort: { date: -1 } },
        {
          $group: {
            _id: "$from",
            from: {
              $first: "$from"
            },
            to: {
              $first: "$to"
            },
            conversation: {
              $first: "$conversation"
            },
            date: {
              $first: "$date"
            }
          }
        },
        {
          $lookup: {
            from: "conversations",
            localField: "conversation",
            foreignField: "_id",
            as: "conversation"
          }
        },
        { $unwind: { path: "$conversation" } },
        {
          $project: {
            from: {
              $cond: { if: { $eq: ["$to", id] }, then: "$from", else: "$to" }
            },
            to: {
              $cond: { if: { $eq: ["$to", id] }, then: "$to", else: "$from" }
            },
            conversation: "$conversation"
          }
        }
      ],
      function(err, docs) {
        if (err) console.log(err);
        else console.log("docs", docs);

        return res.json(docs);
      }
    );

Despite following this structure, the query continues to return an empty array. What could be causing this issue? Additionally, I am aiming to populate the conversation field by utilizing the $lookup, but it seems like there might be a fundamental flaw in my approach since no documents are being found.

Answer №1

Finally cracked the code! To all those who encounter a similar issue, check out this helpful answer. Remember, the id string needs to be converted into an ObjectID.


Here's how I tackled the problem:

    await MostRecentMessages.aggregate(
      [
        {
          $match: {
            $or: [
              { from: mongoose.Types.ObjectId(id) },
              { to: mongoose.Types.ObjectId(id) }
            ]
          }
        },
        { $project: { _id: 1, from: 1, to: 1, conversation: 1, date: 1 } },
        { $sort: { date: -1 } },
        {
          $group: {
            _id: "$sender",
            from: { $first: "$from" },
            to: { $first: "$to" },
            date: { $first: "$date" },
            conversation: { $first: "$conversation" }
          }
        }
      ],
      function(err, docs) {
        if (err) console.log(err);
        else console.log("docs", docs);

        return res.json(docs);
      }
    );

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

jQuery providing incorrect measurements for an element's height

I am encountering an issue with obtaining the height of the #header element in my AngularJS application. Despite using jQuery, the returned height seems to be incorrect. The current code snippet looks like this: $(document).ready(function() { function ...

Do async functions in javascript function synchronously in reality?

I am currently exploring the inner workings of asynchronous code in Javascript. From my understanding, there exists a single thread in JS responsible for executing tasks in a queue. It can progress to the next task only after finishing the current one, whe ...

Creating a directive in AngularJS to automatically populate select options with custom values

As someone who is relatively new to creating directives, I am looking to develop a directive that will assist me in my application. What I aim to achieve is a select element directive that comes pre-populated with options and is self-contained. All I need ...

What is the best way to send an array of grouped data to a table

Here's how I organized the array: { "2023-10-01": [ { "emp_id": 1, "name": "Aruna", "code": "DO", "date": "2023-10-01" }, { &qu ...

Adjusting the size of images in a Bootstrap lightbox gallery

I am currently working on a website for an artist, making the galleries a key aspect. The website is built using Bootstrap, with the Lightbox for Bootstrap plugin being used for the galleries. Everything seems to be working well in terms of adjusting the i ...

Storing data in a TypeBuffer and then retrieving it from a file can lead to surprising outcomes

Upon executing the following code: var list = new Uint32Array(16); for (var i=0; i<16; ++i) list[i] = i; fs.writeFileSync("list", new Uint8Array(list).buffer); console.log([].slice.call(new Uint32Array(fs.readFileSync("list")))); We anticipate the out ...

How come executing a function in the Node.js REPL using )( actually functions?

In JavaScript, why is it possible to call a function like this when tested with node.js: ~$ node > function hi() { console.log("Hello, World!"); }; undefined > hi [Function: hi] > hi() Hello, World! undefined > hi)( // Why does this work? Hell ...

Choose children input textboxes based on the parent class during the onFocus and onBlur events

How can I dynamically add and remove the "invalid-class" in my iti class div based on focus events in an input textbox, utilizing jQuery? <div class="form-group col-md-6"> <div class="d-flex position-relative"> & ...

Using localized strings in Spring and jQuery validation: Best practices

Consider this form as an illustration: <form id="login_form" method="post" action="/rest/auth/auth"> <div id="login_email" class="row margin-top-50"> <div class="col-md-12" id="input_container"> <input id="log ...

Displaying a message in a modal popup once an existing modal popup has been closed - Angular

Hello, I am new to using Angular and I have a question. How can I show a success message in another popup after sending an email from a modal popup? Here is a snippet of my code: <div id="modalViewImportCode" class="modal fade btm-border" role="dialog" ...

The conditional logic in AngularJS is not functioning as expected

https://i.sstatic.net/RvqYQ.pngMy code seems to have an issue with the if/else statement. I am checking the value of data.success which should contain either true or false. However, when I use (data.success === true) in the if statement, the else block e ...

Tips on how to remove the first column from a jQuery hover effect

Currently, I have a function that enables hover events on a table. Right now, it excludes the header row but I also need it to exclude the first column. Any suggestions on how to do this? $(".GridViewStyle > tbody > tr:not(:has(table, th))") ...

Implementing file uploads with Bootstrap, jQuery, and Laravel

Looking to incorporate the blueimp jquery file upload feature into my Laravel app. Check it out here: https://github.com/blueimp/jQuery-File-Upload The form is set up and working properly with the plugin, but facing issues with creating server-side script ...

Ways to filter out specific fields when returning query results using Mongoose

I was wondering about the code snippet below: Post.create(req.body) .then(post => res.status(201).json(post)) .catch(err => res.status(500).json(err)) While this code works perfectly, I am curious about excluding a specific field, such as the __v fi ...

What is the best way to remove excess content that falls outside the viewBox?

Is there a function or method to trim a path that extends beyond the viewbox rather than simply concealing it? I am currently using svg-edit, which has a specific viewbox or canvas area. Any elements drawn outside of this canvas remain hidden. However, wh ...

Leveraging Vuex stores in a modular WebPack setup

I am currently working on a web application where each page of the site has 2 JS files: a global "bootstrap.js" file that is consistent across every page and a custom JS file specific to each page. I've run into an issue where I want these files to sh ...

Develop interactive web applications using Typescript

Having difficulty compiling and executing the project correctly in the browser. The "master" branch works fine, but I'm currently working on the "develop" branch. It's a basic web project with one HTML file loading one TS/JS file that includes i ...

Navigating the dynamic components in Vue using dynamic routing

I'm currently developing an application that helps users manage maintenance tasks. I have successfully created a component to display all the data stored in an array of objects. However, I am facing a challenge in redirecting users to different pages ...

The Context API leaves me feeling lost and confused

I am currently utilizing Auth0 for user sign up. My goal is to extract the user id listed under sub:value, and then add it to my database to associate it with a user's post. To achieve this, I am attempting to utilize a Context API to retrieve the use ...

Display all elements on a webpage using Javascript without the need for scrolling

I'm looking for a way to ensure all items on a webpage load immediately, without having to scroll down multiple times before running a script to find a specific item. Is there a method to have all items load at once without the need to manually scroll ...