0

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

  • Please trim your code to make it easier to find your problem. Follow these guidelines to create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Community Feb 08 '23 at 15:48

2 Answers2

0

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);
                }
            },
        );
    };
Jacob
  • 1,697
  • 8
  • 17
0

@Jacob's answer can be further simplified to,

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

Demo

Noel
  • 10,152
  • 30
  • 45
  • 67