graphql-compose / graphql-compose-mongoose

Mongoose model converter to GraphQL types with resolvers for graphql-compose https://github.com/nodkz/graphql-compose
MIT License
709 stars 94 forks source link

Relation detection #409

Closed maheraldous closed 2 years ago

maheraldous commented 2 years ago

Hello

I know if I have 2 Schema like one user and one for group I won't be able to detect the relation between them out of the box even if I use your tool. So I need to make my own resolver or edit some of your resolver. What I want to get is:

1 - User created

2 - Group Created by User

3 - So now We have one user and one Group so if we have these schemas below:

User

export const UserSchema = new mongoose.Schema({
  username: {
      type: String,
  },
  groupIds: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'GROUP'
  }],
},
{
  collection: 'user',
  timestamps: true,
});

// -----------------------------------------------------------------------------
// DEFINE MONGOOSE MODEL
export const UserMD = mongoose.model('USER', UserSchema);

Group

export const GroupSchema = new mongoose.Schema({
  name: {
      type: String,
  },
  userIds: [{
      type: mongoose.Schema.Types.ObjectId,
      ref: 'USER'
  }],
},
{
  collection: 'tag',
  timestamps: true,
})

// -----------------------------------------------------------------------------
// DEFINE MONGOOSE MODEL
export const GroupMD = mongoose.model('GROUP', GroupSchema);

4 - We will see that in the Database

5 - We assigned the User ID to the Group so we have this:

{
  Group :{
    id: "1"
    name: "First Group",
    user: ["10"]
  }
}

6 - If we look then at the user we see that the user dose not have the group ID that he or she created:

{
  User:{
    id: "10"
    username: "First User",
    group: [""] // empty
  }
}

7 - Solving it by updateing the user with the Group ID or by editing the Group resolver so that when User create the Group he add the Group ID to his Group Array

8 - So this is how to do it as we do even without graphql-compose-mongoose

I wonder if there is some plugin or some way to do that without doing it like the old way. Since your tool is connected with Mongoose isn't possible to watch the Models changes. Like if User have a Group ID but that Group dose not have the User ID then delete the Group ID from the User or Add the User ID to the Group. So do this based on what we made first.

Like if we just added the Group ID to the User then this means that we should tell the Group to also Add User ID.

These are my relations without any edit:

UserTC.addRelation(
    'groups',
    {
        resolver: (author, args, context, info) => {
            return GroupTC.mongooseResolvers.dataLoaderMany();
        },
        prepareArgs: { // resolver `findByIds` has `_ids` arg, let provide value to it
            _ids: (source) => source.groupIds, // USER.groupIds
        },
        projection: { groupIds: true },
    }
);

GroupTC.addRelation(
    'users',
    {
        resolver: (author, args, context, info) => {
            return UserTC.mongooseResolvers.dataLoaderMany();
        },
        prepareArgs: { 
            _ids: (source) => source.userIds, // GROUP.userIds 
        },
        projection: { userIds: true }, 
    }
);
nodkz commented 2 years ago

I think it is better to solve it via mongoose plugin or middleware on post hook. Just write your own plugin and attach it to models.

maheraldous commented 2 years ago

Can we made it into the core of this tool by using Mongoose Watch

Something like this

UserMD.watch().on("change", (data) => {
    if (data.operationType === "insert") {
      console.log("User inserted: ", data.fullDocument);
    }

    if (data.operationType === "replace") {
      console.log("User updated: ", data.fullDocument);
    }

    if (data.operationType === "delete") {
      // Like here the user was deleted so it's time to detelet his or her information from all the groups.
      console.log("User deleted: ", data._id);
    }
 });

This is the most common Mongo DB and GraphQL issue so if this tool solve it like it solved the query long time making then this tool will get a boost up.

nodkz commented 2 years ago

Yep, it's a great feature request. I will try to make some R&D this week.

maheraldous commented 2 years ago

This video may help to get more deep. https://www.youtube.com/watch?v=agW9TXJxzlE