programing

일대일 관계를 가진 Mongoose 문서 참조

muds 2023. 5. 21. 12:03
반응형

일대일 관계를 가진 Mongoose 문서 참조

저는 새로운 프로젝트를 위한 데이터베이스 구조를 설계하는 일을 하고 있습니다. 그리고 저는 MongoDB, 그리고 분명히 Mongoose에 꽤 익숙합니다.

저는 몽구스 인구 문서를 읽었는데, 몽구스 인구 문서는 일대일 관계를 가지고 있습니다.Person많은 사람들에게 문서화.Story문서, 하지만 나를 혼란스럽게 하는 부분은 대신에 어디에 있는지입니다.Story무엇을 참조하는 문서Person그것이 속한 문서,Person스키마가 설정되어 있으므로 무엇의 배열을 가지고 있습니다.Story문서화합니다.

저는 이것과 매우 유사한 것을 설정하고 있습니다.하지만 저는 계속해서 새로운 것을 만드는 것이 더 쉬울 것이라고 생각합니다.Story을 가질 수 있는 문서.Person문서 ID.하지만 제가 조인을 사용하는 MySQL 관계에 더 익숙하기 때문일 수도 있습니다.

만약 이것이 그것을 하는 가장 좋은 방법이라면 (그리고 문서에 있기 때문에, 나는 그것이 그렇다고 확신합니다.Story문서가 생성되었습니다. 관련된 스토리 배열을 업데이트하는 가장 좋은 방법은 무엇입니까?People그것이 속한 문서?기존 문서를 업데이트하여 다른 문서에 대한 참조를 추가하거나 삭제하는 예를 찾아보았지만 찾을 수 없었습니다.

이것은 제가 방금 간과했던 쉬운 해결책이라고 확신합니다. 하지만 어떤 도움이든 좋을 것입니다.감사합니다!

인구를 참조하십시오. 여기서 Mongoose에서 예제를 추출합니다.

var mongoose = require('mongoose')
, Schema = mongoose.Schema

var personSchema = Schema({
  _id     : Schema.Types.ObjectId,
  name    : String,
  age     : Number,
  stories : [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});

var storySchema = Schema({
  _creator : { type: Schema.Types.ObjectId, ref: 'Person' },
  title    : String,
  fans     : [{ type: Schema.Types.ObjectId, ref: 'Person' }]
});

var Story  = mongoose.model('Story', storySchema);
var Person = mongoose.model('Person', personSchema);

예를 들어,Story모델 스토어 관련Person._idStory._creator의 문서를 찾을 때Story사용할 수 있습니다.populate()속성을 정의하는 방법Person다음과 같이 동시에 검색할 모델:

Story.findOne({_id: 'xxxxxxx'}).populate('person', 'name age').exec(function(err, story) {
  console.log('Story title: ', story.title);
  console.log('Story creator', story.person.name);
});

이것이 당신이 찾고 있는 것이라고 믿습니다.또는 중첩된 컬렉션을 대신 사용할 수 있습니다.

이 질문에 대한 이전 답변은 도움이 되었지만 보다 자세한 코드를 보는 것이 유용할 수 있습니다.아래 코드는 내 애플리케이션용 Express.js 백엔드의 코드입니다.내 애플리케이션은 사용자들이 리뷰를 쓸 수 있게 해줍니다.사용자에게 문의할 때 사용자가 작성한 모든 리뷰를 반환합니다.

user_model.js

import mongoose, { Schema } from 'mongoose';


const UserSchema = new Schema({
  firstname: String,
  lastname: String,
  username: { type: String, unique: true },
  reviews: [{ type: Schema.Types.ObjectId, ref: 'Review' }],
}, {
  toJSON: {
    virtuals: true,
  },
});

const UserModel = mongoose.model('User', UserSchema);
export default UserModel;

review_model.js

import mongoose, { Schema } from 'mongoose';

const ReviewSchema = new Schema({
  body: String,
  username: String,
  rating: Number,
}, {
  toJSON: {
    virtuals: true,
  },
});

const ReviewModel = mongoose.model('Review', ReviewSchema);
export default ReviewModel;

review_controller.js

// . . .
export const createReview = (req, res) => {
    const review = new Review();
    review.username = req.body.username;
    review.rating = req.body.rating;
    review.body = req.body.body;
    review.save()
      .then((result) => {
        User.findOne({ username: review.username }, (err, user) => {
            if (user) {
                // The below two lines will add the newly saved review's 
                // ObjectID to the the User's reviews array field
                user.reviews.push(review);
                user.save();
                res.json({ message: 'Review created!' });
            }
        });
      })
      .catch((error) => {
        res.status(500).json({ error });
      });
};

user_controller.js

 export const createUser = (req, res) => {
   const user = new User();
   user.username = req.body.username;
   user.email = req.body.email;
   user.save()
       .then((result) => {
            res.json({ message: 'User created!', result });
        })
        .catch((error) => {
          res.status(500).json({ error });
        });
    };

// . . .
// returns the user object associated with the username if any
// with the reviews field containing an array of review objects 
// consisting of the reviews created by the user
export const getUser = (req, res) => {
    User.findOne({ username: req.params.username })
      .populate('reviews')
      .then((result) => {
        res.json(result);
      })
      .catch((error) => {
        res.status(500).json({ error });
      });
  };

인구 문서에 언급된 바와 같이.

var aaron = new Person({ _id: 0, name: 'Aaron', age: 100 });

aaron.save(function (err) {
  if (err) return handleError(err);

  var story1 = new Story({
    title: "Once upon a timex.",
    _creator: aaron._id    // assign the _id from the person
  });

  story1.save(function (err) {
    if (err) return handleError(err);
    // thats it!
  });
  //then add story to person
  aaron.stories.push(story1);
  aaron.save(callback);
});

단방향 또는 양방향 관계

한 가지 더 생각해 볼 수 있는 가능성이 있습니다.양방향 연관성이 정말 필요합니까?아니면 그것을 저장하는 것만으로 충분할까요?_creator의 각의에Story저장하지 마십시오.list of stories 자의에 Person검색에서 스토리 목록을 계속 조회할 수 있습니다.

let allStoriesOfOneCreator = Stories.find({_creator: person._id});

https://docs.mongodb.com/manual/tutorial/model-referenced-one-to-many-relationships-between-documents/

결국 이는 앱의 요구 사항에 따라 달라집니다.당신은 얼마나 자주 창작자의 이야기가 필요합니까?

일대일 관계를 만드는 좋은 방법이 있습니다.

  1. 먼저 Comment.js에서 Comment 모델을 정의합니다.
const mongoose = require("mongoose");

const Comment = mongoose.model(
  "Comment",
  new mongoose.Schema({
    username: String,
    text: String,
    createdAt: Date
  })
);

module.exports = Comment;
  1. Tutorial.js에서 다음과 같은 주석 배열을 추가합니다.


const mongoose = require("mongoose");

const Tutorial = mongoose.model(
  "Tutorial",
  new mongoose.Schema({
    title: String,
    author: String,
    images: [],
    comments: [
      {
        type: mongoose.Schema.Types.ObjectId,
        ref: "Comment"
      }
    ]
  })
);

module.exports = Tutorial;
  1. server.js에서 createComment 함수를 추가합니다.

const createComment = function(tutorialId, comment) {
  return db.Comment.create(comment).then(docComment => {
    console.log("\n>> Created Comment:\n", docComment);

    return db.Tutorial.findByIdAndUpdate(
      tutorialId,
      { $push: { comments: docComment._id } },
      { new: true, useFindAndModify: false }
    );
  });
};

스크립트 사용자인 경우:

import mongoose from 'mongoose';

interface PromotionAttrs {
  price: number;
  startDate: Date;
  endDate: Date;
}

export interface PromotionDoc extends mongoose.Document {
  price: number;
  startDate: string;
  endDate: string;
}

interface PromotionModel extends mongoose.Model<PromotionDoc> {
  build(attrs: PromotionAttrs): PromotionDoc;
}

const promotionSchema = new mongoose.Schema({
  price: {
    type: Number,
  },
  startDate: {
    type: mongoose.Schema.Types.Date,
  },
  endDate: {
    type: mongoose.Schema.Types.Date,
  },
});

promotionSchema.statics.build = (attrs: PromotionAttrs) => {
  return new Promotion(attrs);
};

const Promotion = mongoose.model<PromotionDoc, PromotionModel>(
  'Promotion',
  promotionSchema
);

export { Promotion };
import mongoose from 'mongoose';
import { PromotionDoc } from './promotion';

interface ProductAttrs {
  name: string;
  promotions?: PromotionDoc[];
}

interface ProductModel extends mongoose.Model<ProductDoc> {
  build(attrs: ProductAttrs): any;
}
interface ProductDoc extends mongoose.Document {
  name: string;
  promotions?: PromotionDoc[];
}
const productSchema = new mongoose.Schema({
  promotions: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Promotion',
    },
  ],
});

productSchema.statics.build = (attrs: ProductAttrs) => {
  return new Product(attrs);
};
const Product = mongoose.model<ProductDoc, ProductModel>(
  'Product',
  productSchema
);

export { Product };
const product = await Product.findById(productId);

    if (!product) {
      throw new NotFoundError();
    }
const promotion = Promotion.build({
        price,
        startDate,
        endDate,
      });
      await promotion.save();
      product.promotions?.push();
      await product.save();

언급URL : https://stackoverflow.com/questions/34985846/mongoose-document-references-with-a-one-to-many-relationship

반응형