skip to Main Content

How to get conversations that have exact matching ids in the "conversation_members" array using Loopback?

I have a collection in Loopback with the following structure:

"conversation" : [
  {
            "id": "e03e8b6b-725a-44aa-8181-56cdcebe9a45",
            "created_at": "2023-02-02T21:38:22.633Z",
            "conversation_name": "My Conversation",
            "is_group": true,
            "created_by": {
                "id": "123",
                "name": "John Doe"
            },
            "conversation_members": [
                {
                    "id": "123",
                    "name": "John Doe"
                },
                {
                    "id": "456",
                    "name": "Jane Doe"
                },
                {
                    "id": "789",
                    "name": "Jane Doe"
                }
            ]
        },
  {
            "id": "e03e8b6b-725a-44aa-8181-56cdcebe9a45",
            "created_at": "2023-02-02T21:38:22.633Z",
            "conversation_name": "My Conversation",
            "is_group": true,
            "created_by": {
                "id": "123",
                "name": "John Doe"
            },
            "conversation_members": [
                {
                    "id": "123",
                    "name": "John Doe"
                },
                {
                    "id": "456",
                    "name": "Jane Doe"
                },
                {
                    "id": "7891",
                    "name": "Jane Doe"
                }
            ]
        },
  {
            "id": "e03e8b6b-725a-44aa-8181-56cdcebe9a45",
            "created_at": "2023-02-02T21:38:22.633Z",
            "conversation_name": "My Conversation",
            "is_group": true,
            "created_by": {
                "id": "123",
                "name": "John Doe"
            },
            "conversation_members": [
                {
                    "id": "123",
                    "name": "John Doe"
                },
                {
                    "id": "456",
                    "name": "Jane Doe"
                },
                {
                    "id": "789",
                    "name": "Jane Doe1"
                }
            ]
        },
]

And the following LoopBack remoteMethod:

Conversation.remoteMethod('getConversationsByMembers', {
        accepts: { arg: 'membersId', type: 'array', required: true },
        returns: { arg: 'conversations', type: 'array' },
        http: { path: '/getConversationsByMembers', verb: 'post' },
    });

With function:

Conversation.getConversationsByMembers = function (membersId, cb) {
  Conversation.find(
    {
      where: {
        conversation_members: {
          [...]
        },
      },
    },
    function (err, conversations) {
      if (err) {
        cb(err);
      } else {
        cb(null, conversations);
      }
    },
  );
};

I want to write the where clause so that I can get the conversations where the "conversation_members" array contains exact ids, for example, [123, 456, 789]. How can I do this?

I tried both

 Conversation.getConversationsByMembers = function (membersId, cb) {
        Conversation.find(
            {
                where: {
                    conversation_members: {
                        all: [
                            {
                                id: {
                                    inq: membersId.map((id) => id.toString()),
                                },
                            },
                        ],
                    },
                },
            },
            function (err, conversations) {
                if (err) {
                    cb(err);
                } else {
                    cb(null, conversations);
                }
            },
        );
    };

and

Conversation.getConversationsByMembers = function (membersId, cb) {
        Conversation.find(
            {
                where: {
                    conversation_members: {
                        elemMatch: {
                            id: {
                                inq: membersId.map((id) => id.toString()),
                            },
                        },
                    },
                },
            },
            function (err, conversations) {
                if (err) {
                    cb(err);
                } else {
                    cb(null, conversations);
                }
            },
        );
    };

with request body {"membersId": [123,456, 789]}.

I was expecting

"conversation" : [
  {
            "id": "e03e8b6b-725a-44aa-8181-56cdcebe9a45",
            "created_at": "2023-02-02T21:38:22.633Z",
            "conversation_name": "My Conversation",
            "is_group": true,
            "created_by": {
                "id": "123",
                "name": "John Doe"
            },
            "conversation_members": [
                {
                    "id": "123",
                    "name": "John Doe"
                },
                {
                    "id": "456",
                    "name": "Jane Doe"
                },
                {
                    "id": "789",
                    "name": "Jane Doe"
                }
            ]
        },
  {
            "id": "e03e8b6b-725a-44aa-8181-56cdcebe9a45",
            "created_at": "2023-02-02T21:38:22.633Z",
            "conversation_name": "My Conversation",
            "is_group": true,
            "created_by": {
                "id": "123",
                "name": "John Doe"
            },
            "conversation_members": [
                {
                    "id": "123",
                    "name": "John Doe"
                },
                {
                    "id": "456",
                    "name": "Jane Doe"
                },
                {
                    "id": "789",
                    "name": "Jane Doe1"
                }
            ]
        },
]

But the answer was empty array

2

Answers


  1. I’m not familiar with loopback, but the query you’re looking for in vanilla mongo is:

    db.collection.find({
      "conversation_members": {
        "$all": [
          {
            "$elemMatch": {
              "id": "123"
            }
          },
          {
            "$elemMatch": {
              "id": "456"
            }
          },
          {
            "$elemMatch": {
              "id": "789"
            }
          }
        ]
      }
    })
    

    so I imagine that would be translated like so:

     Conversation.getConversationsByMembers = function (membersId, cb) {
            Conversation.find(
                {
                    where: {
                        conversation_members: {
                            all: membersId.map((id) => { 
                                elemMatch: {
                                    id: id.toString()
                                }
                            }),
                        },
                    },
                },
                function (err, conversations) {
                    if (err) {
                        cb(err);
                    } else {
                        cb(null, conversations);
                    }
                },
            );
        };
    
    Login or Signup to reply.
  2. @Jacob’s answer can be further simplified to,

    db.collection.find({
      "conversation_members.id": {
        "$all": [
          "123","456","789"
        ]
      }
    })
    

    Demo

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