Mongoose를 사용하여 검색 또는 생성
있습니다
Page.findById(pageId).then(page => {
const pageId = page.id;
..
});
제 문제는 페이지 ID가 제공되지 않으면, 어떤 조건이 주어지면 사용 가능한 첫 번째 페이지를 가져가야 한다는 것입니다.
Page.findOne({}).then(page => {
const pageId = page.id;
..
});
그러나 페이지를 찾을 수 없는 경우, 새 페이지를 만들고 이 페이지를 사용해야 합니다. 이 작업은 다음과 같이 수행됩니다.
Page.create({}).then(page => {
const pageId = page.id;
..
});
하지만 어떻게 하면 이 모든 것을 가능한 한 적은 줄로 결합할 수 있을까요?
나는 내부에서 많은 논리를 가지고 있습니다.
page => { ... }
그래서 저는 이것을 똑똑하게 하고 싶어서 이렇게 하는 것을 피할 수 있습니다.
if (pageId) {
Page.findById(pageId).then(page => {
const pageId = page.id;
..
});
} else {
Page.findOne({}).then(page => {
if (page) {
const pageId = page.id;
..
} else {
Page.create({}).then(page => {
const pageId = page.id;
..
});
}
});
}
스키마에 정적인 것을 할당할 수 있을 것 같습니다.
pageSchema.statics.findOneOrCreate = function (condition, doc, callback) {
const self = this;
self.findOne(condition).then(callback).catch((err, result) => {
self.create(doc).then(callback);
});
};
Mongoose 문서에 따라:
Model.FindByIdAndUpdate()
"일치하는 문서를 찾아서 업데이트 인수에 따라 업데이트하고 옵션을 전달한 후 발견된 문서(있는 경우)를 콜백으로 반환합니다."
true로 설정된 옵션에서 다음을 수행합니다.
upsert:bool - 개체가 없으면 개체를 만듭니다. 기본값은 false입니다.
Model.findByIdAndUpdate(id, { $set: { name: 'SOME_VALUE' }}, { upsert: true }, callback)
요스벨 퀸테로의 답변과 관련하여, 저는 잘 되지 않았습니다.
pageSchema.statics.findOneOrCreate = function findOneOrCreate(condition, callback) {
const self = this
self.findOne(condition, (err, result) => {
return result ? callback(err, result) : self.create(condition, (err, result) => { return callback(err, result) })
})
}
그런 다음 다음과 같이 사용합니다.
Page.findOneOrCreate({ key: 'value' }, (err, page) => {
// ... code
console.log(page)
})
약속.async/await
판본
Page.static('findOneOrCreate', async function findOneOrCreate(condition, doc) {
const one = await this.findOne(condition);
return one || this.create(doc);
});
사용.
Page.findOneOrCreate({ id: page.id }, page).then(...).catch(...)
또는
async () => {
const yourPage = await Page.findOneOrCreate({ id: page.id }, page);
}
각 스키마는 모델에 대한 인스턴스(instance) 및 정적 메서드를 정의할 수 있습니다.통계량은 방법과 거의 동일하지만 모형에 직접 존재하는 함수를 정의할 수 있습니다.
정적 방법findOneOrCreate
:
pageSchema.statics.findOneOrCreate = function findOneOrCreate(condition, doc, callback) {
const self = this;
self.findOne(condition, (err, result) => {
return result
? callback(err, result)
: self.create(doc, (err, result) => {
return callback(err, result);
});
});
};
이제 당신이 예를 들면,Page
전화하셔도 됩니다findOneOrCreate
:
Page.findOneOrCreate({id: 'somePageId'}, (err, page) => {
console.log(page);
});
단일 라인 솔루션:async/await
:
const page = Page.findOne({}).then(p => p || p.create({})
정적 메서드를 모델에 추가하지 않으려면 다음과 같은 모든 콜백 중첩 수준을 사용하지 않고 몇 가지 항목을 이동할 수 있습니다.
function getPageById (callback) {
Page.findById(pageId).then(page => {
return callback(null, page);
});
}
function getFirstPage(callback) {
Page.findOne({}).then(page => {
if (page) {
return callback(null, page);
}
return callback();
});
}
let retrievePage = getFirstPage;
if (pageId) {
retrievePage = getPageById;
}
retrievePage(function (err, page) {
if (err) {
// @todo: handle the error
}
if (page && page.id) {
pageId = page.id;
} else {
Page.create({}).then(page => {
pageId = page.id;
});
}
});
여기에 게시된 솔루션은 필드 또는 필드 조합에 고유 인덱스가 있을 때 이 패턴이 가장 일반적이라는 것을 무시합니다.이 솔루션은 고유한 인덱스 위반 오류를 올바르게 고려합니다.
mongoose.plugin((schema) => {
schema.statics.findOrCreate = async function findOrCreate(key, attrs) {
try {
return await this.create({ ...attrs, ...key });
} catch (error) {
const isDuplicateOnThisKey =
error.code === 11000 &&
Object.keys(error.keyPattern).sort().join(',') ===
Object.keys(key).sort().join(',');
if (isDuplicateOnThisKey) {
const doc = await this.findOne(error.keyValue);
doc.set(attrs);
return await doc.save();
}
throw error;
}
};
});
용도:
await Post.findOrCreate({ slug: 'foobar' }, { title: 'Foo Bar', body });
이것을 시도해 보세요.
var myfunc = function (pageId) {
// check for pageId passed or not
var newId = (typeof pageId == 'undefined') ? {} : {_id:pageId};
Page.findOne(pageId).then(page => {
if (page)
const pageId = page.id;
else { // if record not found, create new
Page.create({}).then(page => {
const pageId = page.id;
});
}
});
}
언급URL : https://stackoverflow.com/questions/40102372/find-one-or-create-with-mongoose
'programing' 카테고리의 다른 글
'import.meta' 메타 속성은 '--module' 옵션이 'es2020', 'esnext' 또는 'system'.ts(1343)인 경우에만 허용됩니다. (0) | 2023.06.21 |
---|---|
컨트롤러에서 스프링 배치 작업 실행 (0) | 2023.06.21 |
파이어베이스의 FCM 토큰이란 무엇입니까? (0) | 2023.06.21 |
고정 너비를 설정하는 방법은 무엇입니까? (0) | 2023.06.21 |
MongoDB 중첩 문서 $lookup (0) | 2023.06.21 |