简体   繁体   中英

How to get data from a separate collection and join it with a user collection without having a same common id to link both of them in MongoDB?

I have 2 collections in MongoDB namely "users" and "dictionaries". I'm building a simple dictionary (simple form and table) where the users can store any words that they have learned. I have also built authentication for the web app so only registered users have access to the dictionary table.

My problem is I don't know how to link both of the collections because I don't have a common property to do a lookup function. What I would like to do is basically whenever a user logs in, his/her data from the dictionary collection will be rendered in the table.

Do I need to create a common property/id in both collections (that would be redundant no?)?

The User and Dictionary schema are as below; ( The _id should be automatically created in both collections but I think both ids are not the same)

    const userSchema = mongoose.Schema({
      joindate: {
        type: Date,
      },
      fullname: {
        type: String,
      },
      email: {
        type: String,
      },
      password: {
        type: String,
      },
      dateofbirth: {
        type: Date,
      },
    });

  const dictionarySchema = mongoose.Schema({
  word: {
    type: String,
  },
  meaning: {
    type: String,
  },
  example: {
    type: String,
  },
  language: {
    type: String,
  },
  date: {
    type: Date,
  },
});

You can link in 2 ways

  1. Either you store references to the Dictionary model in the User model as an array of references.Then you will be able to fetch the user along with his dictionaries

dictionaries: [{ type: mongoose.Schema.ObjectId, ref: '<Name of Dictionary model>' }]

You can then fetch the dictionaries with the users using populate

UserModel.find({}).populate('dictionaries').exec()

You can find examples in the mongoose documentation https://mongoosejs.com/docs/populate.html

  1. You can store a reference in the Dictionary model as a new field, for eg. creator

creator: { type: mongoose.Schema.ObjectId, ref: <Name of User Model> }

You can then query your Dictionary model to find by creator

DictionaryModel.find({creator: ObjectId(<ObjectId of User>)})

Or if you don't want to link, you can store the dictionaries directly as an array field in your user model

You have your own answer, yes, you need to create a common field/id, which will help us to map each users to their saved words.

If you are worried about storing the common field/id twice in DB, then, you can go with something similar schema like below:

userSchema = {
  joindate:,
  fullname:,
  email:,
  password:,
  dateofbirth:
  dictionaries: [{
    word:,
    meaning:,
    example:,
    language:,
    date:,
  }]
}

The users collection will be having the dictionaries field, where you can push all the words stored by that particular user. And you don't need to do any lookup . As MongoDB is a NoSQL DB, there is no relation at all. You are a free bird.

Update: What I meant by common field is that, something like username or userId . I believe that only logged in user can store the words. Then you can take the logged in user's username, and store it along with other details of words, in dictionaries collection. So, the updated Schema will look like below:

const userSchema = mongoose.Schema({
  username: {
    type: String,
  },
  joindate: {
    type: Date,
  },
  fullname: {
    type: String,
  },
  email: {
    type: String,
  },
  password: {
    type: String,
  },
  dateofbirth: {
    type: Date,
  },
});

const dictionarySchema = mongoose.Schema({
  username: {
    type: String,
  },
  word: {
    type: String,
  },
  meaning: {
    type: String,
  },
  example: {
    type: String,
  },
  language: {
    type: String,
  },
  date: {
    type: Date,
  },
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM