updating...
Query()
Query.prototype.$where()
Query.prototype.Symbol.asyncIterator()
for/ await/ of loop와 사용되는 asyncIterator 를 반환한다.
find() 쿼리문과만 사용된다. 명시적으로 요 매서드를 부를 필요가 없다, 자바스크립트 런타임이 불러 준다.
* asyncIterator()
An AsyncIterator is an Object that returns a sequence of Promises. Since AsyncIterators are AsyncIterables, you can use for await (const value of iterable) {} to easily loop over the values in an AsyncIterator. Calling an async generator function ( async function* () {} ) returns an AsyncIterator.
Query.prototype.all()
Specifies an $all query condition.
Parameters
* [path] : String
* value : Array
expamle:
return TodoModel.find().where('subject').all(['금욜이당', '퇴근 30분 전 입니다. ']);
=
return TodoModel.find().all('subject', ['금욜이당', '퇴근 30분 전 입니다. ']);
??
value에 하나 요소만 쓰면 조회가 잘 되는데 두 개 이상 쓰는 경우 안나옴
Query.prototype.allowDiskUse()
몽고디비 서버가 100MB 이상 이 쿼리의 sort()에 쓸 수 있도록 허락해준다. allowDiskUse() 매서드를 사용하면 QueryExceededMemoryLimitNoDiskUseAllowed 에러를 피할 수 있다.
Parameters
* Boolean
Returns :
<<Query>> this
await query.find().sort({ name: 1 }).allowDiskUse(true);
=
await query.find().sort({ name: 1 }).allowDiskUse();
Query.protptype.and()
Specifies arguments for a $and condition
Parameters :
* Array <<Array>> array of conditions
Return :
* <<Query>> this
example :
const query = TodoModel.find();
query.setOptions({lean:true});
return query.and([{subject: '퇴근 30분 전 입니다. '}, { content: '수정22' }]);
??
또 배열안에 하나의 조건만 넣을 땐 되고 두개를 넣으면 안됨 -> and 교집합이었음,,,
Query.prototype.batchSize()
Specifies the batchSize option
mongoDB쿼리의 결과는 Batch단위로 데이터를 가져온다. 이것을 제어할 수 있는 두 가지 파라미터는 batchSize, limit 값 지정이다.
batchSize() : 한 batch당 가져오는 document 갯수
limit() : 쿼리의 결과로 가져올 총 갯수
BatchSize, limit을 모두 지정하지 않은 경우에는 디폴트값으로 한번 당 101개의 documents를 가져온다. 하지만 Document 하나 당 너무 많은 데이터로 인해 batch 개당 용량이 1MB가 넘어가면 그만 담고 반환한다.
* batchSize vs Limit -> 설정값이 작은 매서드를 우선한다.
* batchSize는 distinct() 매서드와는 사용될 수 없다.
Parameters
* value <<number>>
example :
query.batchSize(100);
???
리턴되는 값이 findAll()과 같다 아래 답변 :
batchSize() instructs the driver to retrieve a certain number of items per time. It'll still get everything from the DB, only a batch at a time.
To make it clearer: If you use batchSize(30) then it'll ask for 30 items then, when you need the 31st, it'll query the next 30 and so forth.
If you need only that number of items, then use limit() (and offset() to set which is the first item)
Docs: http://docs.mongodb.org/manual/reference/method/cursor.batchSize/
출처 : https://stackoverflow.com/questions/32634867/mongoose-mongodb-batchsize30-still-returning-all-results
Query.prototype.box()
Specifies a $box condition
Parameters :
* value <<Object>>
* Upper <<[Array]>> Right Coords
Returns :
* <<Query>> this
Query.prototype.limit()
쿼리가 반환할 도큐먼트의 수를 제한한다.
Parameters
* val <<Number>
* distinct()와 함께 쓰일 수 없다.
example :
const query = TodoModel.find();
query.setOptions({lean:true});
return query.limit(2); // -> documents 2개 반환
Query.prototype.cast()
Casts this query to the schema of model
만약 obj가 있다면 해당 쿼리 대신 obj가 cast된다.
Parameters :
* [model] <<Model>> the model to cast to, If not set, defaults to this.model
* [obj] <<Object>>
Returns :
* <<Object>>
Query.prototype.catch()
resolved되거나 rejected될 Promise를 반환하는쿼리를 실행시킨다. .then()과 짝꿍이지만 오직 rejection 을 위한 handler이다.
Parameters :
* [refect] <<Function>>
Returns :
* <<Promise>>
Query.prototype.center()
Deprecated Alias for circle, Use circle istead.
사라지게 된 매서드, circle 매서드를 대신 사용하기
Query.prototype.centerSphere()
Deprecated, use circle instead.
사라지게 된 매서드, circle 매서드를 대신 사용하기
Specifies a $centerSphere condition
Parameters
* [Path] : <<String>>
* value : <<Object>>
Returns :
* <<Query>> this
Query.prototype.circle()
Specifies a $center or $centerSphere condition
Parameters
* [path] <<String>>
* area <<Object>>
Returns :
* <<Query>> this
Query.prototype.clone()
Make a copy of this query so you can re-execute it.
해당 쿼리의 복사본을 만들어서 이것을 다시 실행시킬 수 있다.
Returns :
* <<Query>> copy
Example :
const query = ToodModel.findOne({subject: '금욜이당'});
query.setOptions({lean:true});
await query.exec();
await query.exec();
// -> ERROR : Query was alread executed
await query.exec();
await query.clone().exec(); // ?? query에 clone 속성이 없다는 오류가 나옴 하지만 실행은 됨
// -> 쿼리 두번 실행 가능!
Query.prototype.collation()
Adds a collation to this op (MongoDB 3.4 and up)
Parameters
* value <<Object>>
Returns :
* <<Query>> this
Query.prototype.comment()
Specifies the comment option
* mongoDB v3.2부터 더이상 사용되지 않음
Parameters
* value <<String>>
* distinct()와 함께 사용될 수 없다.
Example :
const query = TodoModel.find({ subject : '금욜이당'});
query.setOptions({lean: true});
return query.comment('코멘트입니다');
???
postman 결과값은 그대로 find()의 결과값이다. 저 코멘트는 어디서 보는걸까,,,
Query.prototype.count()
Deprecated. use estimatedDocumentCount() function instead.
더이상 사용되지 않는 매서드, estimatedDocumentCount()를 사용하기
Parameters :
* [filter] <<Object> count documents that match this object
* [callback] <<Function>> optional params are (error, count)
Returns :
* <<Query>> this
Query.prototype.countDocuments()
빈 filter{} 를 주었을 때 전체 collection 스캔을 한다는 사실을 제외하고는 count() 와 같은 기능이다. 또한 where / geospatial operators를 처리할 때 count()와 자잘한 차이가 있다고 한다.
Parameters :
* [filter] <<Object>> mongodb selector
* [callback] <<Function>> optional params are (error, count)
Returns :
* <<Query>> this
* countDocuments()와 함께 쓸 수 없는 매서드들과 그 대체매서드로 제안되는 매서드
같이 쓸 수 없는 매서드 | 대체 매서드 |
$where | $expr |
$near | $geoWithin with $center |
$nearSphere | $geoWithin with $centerSphere |
examples:
const countQuery = model.where({'color':'black'}).countDocuments();
=
query.countDocuments({color:'black'}).count(callback);
=
query.countDocuments({color:'black'}, callback);
=
query.where('color':'black').countDocuments(function(err, count) {
if (err) return handleError(err);
console.log('there are %d kittens', count);
});
Query.prototype.estimatedDocumentCount()
조회하는 도큐먼트들의 개수를 반환하는 매서드. 같은 기능을 가진 countDocuments() 보다 빠르다. 왜냐하면 estimatedDocumentCount()는 전체 collection을 스캔하기보다 collection metadata를 사용하기 때문이다.
*** estimatedDocumentCount() 는 filter() 옵션이 적용되지 않는다.
Model.find({foo:bar}).estimatedDocumentCount() = Model.find().estimatedDocumentCount()
Parameters :
* [options] <<Object>> passed transparently to the MongoDB driver
* [callback] <<Function>> optional params are (error, count)
Returns :
* <<Query>> this
Query.prototype.cursor()
Returns a wrapper around a mongodb driver cursor. A QueryCursor exposes a Streams3 interface, as well as a .next() function
.cursor() 매서드는 pre find hooks를 일으키지만 post find hooks는 일으키지않는다.
Parameters
* [options] <<Object>>
Returns :
* <<QueryCursor>>
Query.prototype.deleteMany()
Declare and/or executr this query as ad deleteMany() operation. remove처럼 기능하지만 single of value와 상관없이 collection안에서 filter와 맞는 모든 도큐먼트를 삭제하는 점이 다르다.
deleteMany() 매서드는 deleteMany middleware를 일으킨다.
Parameters :
* [filter] <<Object | Query>> mongodb selector
* [options] <<Object>> optional see Query.prototype.setOptions()
* [callback] <<Function>> optional params are (error, mongooseDeleteResult)
Returns :
* <<Query>> this
example :
return query.deleteMany({ subject: 'test' });
returned value :
deleteMany()매서드는 몽고디비 드라이버의 Collection#deleteMany() 를 부르고 3가지 속성을 가진 promise resolves를 반환한다.
* ok : 1 (if no errors occurred)
* deletedCount : 삭제된 도큐먼트의 수
* n : 삭제된 도큐먼트의 수 ( = deletedCount )
??
deletedCount만 반환됨 !
Query.prototype.deleteOne()
Declare and/or execute this query as a deleteOne() operation. remove와 같은 기능이지만 single option이든 아니든 최대 단 1개의 도큐먼트만 삭제하는 점이 다르다. (db에서 스캔하다가 옵션에 맞는 데이터를 찾으면 해당 도큐먼트만 삭제하고 나옴)
deleteMany() 매서드는 deleteMany middleware를 일으킨다.
Parameters :
* [filter] <<Object | Query>> mongodb selector
* [options] <<Object>> optional see Query.prototype.setOptions()
* [callback] <<Function>> optional params are (error, mongooseDeleteResult)
Returns :
* <<Query>> this
example :
return query.deleteOne({ subject: '금욜이당' });
returned value :
Query.prototype.distinct()
db collection 내, 특정 key의 uique값을 (중복되지 않는 값) 을 알고 싶을 때 사용한다.
Declares or executes a distinct() operation.
passing a callback executes the query.
distinct() 매서드는 어떠한 미들웨어도 trigger하지 않는다.
Parameters :
* [field] <<String>>
* [filter] <<Object | Query>>
* [callback] <<Function>> optional params are (error, arr)
Returns :
* <<Query>> this
example :
distinct(field, conditions, callback)
distinct(field, conditions)
distinct(field, callback)
distinct(field)
distinct(callback)
distinct()
example2 :
return query.distinct('startDate'); // startDate field의 value 중 중복값을 제외한 key값을 반환
or
return query.distinct('subject'); // subject field의 value 중 중복값을 제외한 key값을 반환
returned values :
Query.prototype.elemMatch()
Specifies an $elemMatch condition
Parameters :
* path <<String | Object | Function>>
* filter <<Object | Function>>
Returns :
* <<Query>> this
Example :
query.elemMatch('comment', { author: 'qutobot', votes: {$gte: 5}})
=
query.where('comment').elemMatch({ author: 'qutobot', votes: {$gte: 5}})
???
Can't use $elemMatch with String 오류가 나옴! path에 string도 된다고 적혀있는데 왜일까,,,, ???
Query.prototype.equals()
Specifies the complementary comparison value for paths specified with where()
Parameters :
* value <<Object>>
Returns :
* <<Query>> this
example :
return query.where('subject').equals('테스트');
=
return query.where('subject', '테스트');
returned value :
Query.prototype.error()
Gets/sets the error flag on this query. 만약 flag 가 undefined 또는 null이 아니라면 exec() promise는 실행되지않고 거절된다.
Parameters :
* error <<Error | null >> if set, exec() will fail fast before sending the query to MongoDB
Returns :
* <<Query>> this
example :
return query.error(); // get current error value
or
return query.error(undefined) // 에러가 안난다. ??
or
return query.error(null); // unset the current error -> 요건 에러가 안난다. ?? 왜징
or
return query.error(new Error('에러입니다.'));
error() 요 안에 들어가는 걸 flag라고 하는 것 같다. () 안에 flag에 error메세지를 전달할 수 있고 () 빈 값인 경우 에러가 난다. null or undefined가 들어가면 에러가 안남!
returned value :
Query.prototype.exec()
Executes the query. 쿼리문을 실행시킨다.
Parameters :
* [operation] <<String | Function>>
* [callback] <<Function>> optional params depend on the function being called
Returns :
* <<Promise>>
example :
return query.exec();
or
return query.exec('find');
Query.prototype.exists()
Specifies an $exists condition
특정 컬럼이 있거나 없는 경우의 쿼리문을 작성하고자 할 때 사용
mySQL에서는 모든 row (document)에 필드가 동일하게 있지만 mongoDB는 다를 수도 있어서 이런 매서드가 있는 것 같다.
Parameters :
* [path] <<String>>
* value <<Boolean>>
Return :
* <<Query>> this
example :
return TodoModel.where('subject').exists(); // 오류 - exists에 최소1-2 인자값 필요
or
return TodoModel.where('subject').exists(true);
// subject라는 필드가 있는 모든 도큐먼트들 반환
or
return TodoModel.where('subject').exists(false);
// subject라는 필드가 없는 모든 도큐먼트들 반환
or
return TodoModel.find().exists('subject', true);
// subject라는 필드가 있는 모든 도큐먼트를 반환
or
return TodoModel.find().exist('subject', false);
// subject라는 필드가 없는 모든 도큐먼트를 반환
or
return TodoModel.find().exists('subjecttttt', false);
// subjecttttt 라는 필드 값이 없는 도큐먼트 반환
Query.prototype.explain()
Sets the explain option, 실제 쿼리 결과 대신 자세한 실행 상태를 반환한다. explain() 매서드는 쿼리에 어떤 index를 사용하는지에 따라 매우 유용하다.
query.explain(v) === query.setOptions({ explain: v})
Parameters :
* [verbose] <<String>> The verbosity mode. Either 'queryPlanner', 'executionStats', or 'allPlansExecution'.
디폴트 값 : 'queryPlanner'
Returns :
* <<Query>> this
example :
return TodoModel.find({ subject: '몽고라니ㅣ' }).explain('queryPlanner');
returned value :
{
"explainVersion": "1",
"queryPlanner": {
"namespace": "tabling.todo",
"indexFilterSet": false,
"parsedQuery": {
"subject": {
"$eq": "몽고라니ㅣ"
}
},
"maxIndexedOrSolutionsReached": false,
"maxIndexedAndSolutionsReached": false,
"maxScansToExplodeReached": false,
"winningPlan": {
"stage": "COLLSCAN", // 전체 스캔
"filter": {
"subject": {
"$eq": "몽고라니ㅣ"
}
},
"direction": "forward"
},
"rejectedPlans": []
},
"executionStats": {
"executionSuccess": true,
"nReturned": 3,
"executionTimeMillis": 0,
"totalKeysExamined": 0,
"totalDocsExamined": 39,
"executionStages": {
"stage": "COLLSCAN",
"filter": {
"subject": {
"$eq": "몽고라니ㅣ"
}
},
"nReturned": 3,
"executionTimeMillisEstimate": 0,
"works": 41,
"advanced": 3,
"needTime": 37,
"needYield": 0,
"saveState": 0,
"restoreState": 0,
"isEOF": 1,
"direction": "forward",
"docsExamined": 39
},
"allPlansExecution": []
},
"command": {
"find": "todo",
"filter": {
"subject": "몽고라니ㅣ"
},
"projection": {},
"$db": "tabling"
},
"serverInfo": {
"host": "Planningui-MacBook-Pro.local",
"port": 27017,
"version": "5.0.3",
"gitVersion": "657fea5a61a74d7a79df7aff8e4bcf0bc742b748"
},
"serverParameters": {
"internalQueryFacetBufferSizeBytes": 104857600,
"internalQueryFacetMaxOutputDocSizeBytes": 104857600,
"internalLookupStageIntermediateDocumentMaxSizeBytes": 104857600,
"internalDocumentSourceGroupMaxMemoryBytes": 104857600,
"internalQueryMaxBlockingSortMemoryUsageBytes": 104857600,
"internalQueryProhibitBlockingMergeOnMongoS": 0,
"internalQueryMaxAddToSetBytes": 104857600,
"internalDocumentSourceSetWindowFieldsMaxMemoryBytes": 104857600
},
"ok": 1
}
index걸린 isDone field로 찾는 경우
return TodoModel.find({ isDone: true }).explain('queryPlanner');
returned value :
{
"explainVersion": "1",
"queryPlanner": {
"namespace": "tabling.todo",
"indexFilterSet": false,
"parsedQuery": {
"isDone": {
"$eq": true
}
},
"maxIndexedOrSolutionsReached": false,
"maxIndexedAndSolutionsReached": false,
"maxScansToExplodeReached": false,
"winningPlan": {
"stage": "FETCH",
"inputStage": {
"stage": "IXSCAN", /// index scan
"keyPattern": {
"isDone": 1
},
"indexName": "isDone_1",
"isMultiKey": false,
"multiKeyPaths": {
"isDone": []
},
"isUnique": false,
"isSparse": false,
"isPartial": false,
"indexVersion": 2,
"direction": "forward",
"indexBounds": {
"isDone": [
"[true, true]"
]
}
}
.
.
.
Query.prototype.find()
selector에 맞는 모든 도큐먼트를 배열에 담아 반환
만약 너무 많은 도큐먼트 존재 시에 use Query.prototype.cursor()
Parameters :
* [filter] <<Object | ObjectId>> mongodb selector. If not specified, returns all documents.
* [callback] <<Function>>
Returns :
* <<Query>> this
example :
return TodoModel.find({ isDone: true });
or
return TodoModel.find({ isDone: true }, () => { ?? query was already executed error
console.log('find test');
});
Query.prototype.findOne()
slector에 맞는 도큐먼트 1개 반환 (db에서 옵션에 맞는 도큐먼트를 처음 찾게되면 첫 데이터를 들고 바로 나옴)
만약 조건이 없다면 mongoose 는 빈 findOne 명령문을 mongoDB에 보내고 mongoDB는 임의적인 도큐먼트 1개를 반환한다. _id를 사용한 쿼리문을 작성한다면 Model.findById()를 대신 사용하면 좋다.
findOne()매서드는 findOne() 미들웨어를 trigger하지 않는다.
Parameters :
* [filter] <<Object>> mongodb selector
* [projection] <<Object>> optional fields to return
* [options] <<Object>> see setOptions()
* [callback] <<FUnction>> optional params are (error, document)
Returns :
* <<Query>> this
하나의 single document 반환
example :
return TodoModel.findOne({ isDone: true});
Query.prototype.findOneAndDelete()
조건에 맞는 도큐먼트를 찾고 제거한다. 그리고 찾은 도큐먼트를 callback에 전달한다.
It triggers findOneAndDelete() 미들웨어
* findOneAndRemove()와 다른 점 : findOneAndDelete()와 대조적으로, findOneAndRemove()는 MongoDB 의 findAndModify() command가 되었다. mongoose 사용 케이스 대부분에게는 이러한 구별이 너무 세세한 것에 얽매이는 느낌이 없지않아 있다. 정말 쓰지 않아야할 이유가 있지 않는 이상 findOndAndDelete()를 쓰는게 좋다.
Parameters :
* [conditions] <<Object>>
* [options] <<Object>>
options | |
[options.rawResult] <<Boolean>> | true일 경우 mongoDB driver로부터 raw result를 반환 |
[options.session=null] <<ClientSession>> | The session associated with this query. See transactions docs |
[options.strict] <<Boolean | String>> | overwrites the schema's strict mode option |
* [callback] <<Function>>. optional params are (error, document)
Returns :
* <<Query>> this
Available options
* sort
* maxTimeMS
* rawResult
example :
TodoModel.where().findOneAndDelete(conditions, options, callback) // executes
TodoModel.where().findOneAndDelete(conditions, options) // returns Query
TodoModel.where().findOneAndDelete(conditions, callback) // executes
TodoModel.where().findOndAndDelete(conditions) // returns Query
TodoModel.where().findOneAndDelete(callback) // executes
TodoModel.where().findOneAndDelete() // returns Query
callback이 있으면 executes
return TodoModel.findOneAndDelete({ isDone: false }, { rawResult: true });
returned value :
Query.prototype.findOneAndRemove()
Issues a mongodb findAndModify remove command
조건에 맞는 도큐먼트를 찾아서 제거한다. 찾은 도큐먼트는 callback으로 보낸다.
This function triggers findOneAndRemove().
Available Options :
* sort
* maxTimeMs
* rawResult
Parameters :
* [conditions] <<Object>>
* [options] <<Object>>
options | |
[options.rawResult] <<Boolean>> | true인 경우 raw result from the MongoDB driver 반환 |
[options.session = null] <<ClientSession>> | The session associated with this query. See transactions docs |
[options.strict] <<Boolean | String>> | overwrites the schema's strict mode option |
* [callback] <<Function>> optional params are ( error, document )
example :
TodoModel.where().findOneAndRemove(conditions, options, callback) // executes
TodoModel.where().findOneAndRemove(conditions, options) // returns Query
TodoModel.where().findOneAndRemove(conditions, callback) // executes
TodoModel.where().findOndAndRemove(conditions) // returns Query
TodoModel.where().findOneAndRemove(callback) // executes
TodoModel.where().findOneAndRemove() // returns Query
example2 :
return TodoModel.findOneAndRemove({ isDone: false }, { rawResult: false });
returned value :
Query.prototype.findOneAndReplace()
Issues a MongoDB findOneAndReplace command
조건에 맞는 도큐먼트를 찾아 replace
This function triggers findOneAndReplace().
Parameters :
* [filter] <<Object>>
* [replacement] <<Object>>
* [options] <<Object>>
options | |
[options.rawResult] <<Boolean>> | true일 경우, raw result from the MongoDB driver 반환 |
[options.session=null] <<ClientSession>> | The session associated with this query. See transactions docs |
[options.strict] <<Boolean | String>> | overwrites the schema's strict mode option |
[options.new=false] <<Boolean>> | 디폴트 값으로 findOneAndUpdate()는 update이전의 값을 반환한다. new : true로 설정 시 updated된 값, 수정 이후의 값을 반환 |
[options.lean] <<Object>> | mongoose wil return plain javaScript object |
[options.session=null] <<ClientSession>> | The session associated with this query. See transactions docs |
[options.strict] <<Boolean | String>> | overwrites the schema's strict mode option |
[options.timestamps=null] <<Boolean>> | false경우 schema-level timestamps are enabled, skip timestamps for this update. 이 옵션은 overwrites timestamps, does nothing 만약 스키마 레벨 타임스탬프가 설정되어 있지 않으면 아무 영향이 없다. |
[options.returnOriginal=null] <<Boolean>> | An alias for the new options. false 인 경우 new : true와 같다. |
* [callback] <<Function>> optional params are (error, document)
Returns :
* <<Query>> this
Available options
* sort
* maxTimeMS
* rawResult
example :
TodoModel.where().findOneAndReplace(filter, replacement, options, callback); // executes
TodoModel.where().findOneAndReplace(filter, replacement, options); // returns Query
TodoModel.where().findOneAndReplace(filter, replacement, callback); // executes
TodoModel.where().findOneAndReplace(filter); // returns Query
TodoModel.where().findOneAndReplace(callback); // executes
TodoModel.where().findOneAndReplace(); // returns Query
example 2 :
return TodoModel.findOneAndReplace(
{ subject: 'ㅇ' },
{
subject: '몽고디비테스트',
content: '내용444',
startDate: new Date('2020-10-10'),
finishDate: new Date('2022-02-02'),
},
{
lean: true,
new: true,
},
);
};
-> 조건에 맞는 하나 도큐먼트를 찾아 replacement로 대체한다.
Query.prototype.findOneAndUpdate()
Issues a MongoDB findAndModify command
조건에 맞는 도큐먼트를 찾아 수정
This function triggers findOneAndUpdate().
Parameters :
* [filter] <<Object | Query>>
* [replacement] <<Object>>
* [options] <<Object>>
options | |
[options.rawResult] <<Boolean>> | true일 경우, raw result from the MongoDB driver 반환 |
[options.session=null] <<ClientSession>> | The session associated with this query. See transactions docs |
[options.strict] <<Boolean | String>> | overwrites the schema's strict mode option |
[options.new=false] <<Boolean>> | 디폴트 값으로 findOneAndUpdate()는 update이전의 값을 반환한다. new : true로 설정 시 update된 값, 수정 이후의 값을 반환 |
[options.lean] <<Object>> | mongoose wil return plain javaScript object |
[options.session=null] <<ClientSession>> | The session associated with this query. See transactions docs |
[options.strict] <<Boolean | String>> | overwrites the schema's strict mode option |
[options.timestamps=null] <<Boolean>> | false경우 schema-level timestamps are enabled, skip timestamps for this update. 이 옵션은 overwrites timestamps, does nothing 만약 스키마 레벨 타임스탬프가 설정되어 있지 않으면 아무 영향이 없다. |
[options.returnOriginal=null] <<Boolean>> | An alias for the new options. false 인 경우 new : true와 같다. |
* [callback] <<Function>> optional params are (error, document)
Available options
* new
* upsert
* fields
* sort
* maxTimeMS
* runValidators
* setDefaultsOnInsert
* rawResult
example :
query.findOneAndUpdate(condition, update, options, callback); // executes
query.findOneAndUpdate(conditions, update, options); // returns Query
query.findOneAndUpdate(conditions, update, callback); // executs
query.findOneAndUpdate(conditions, update); // returns Query
query.findOneAndUpdate(update, callback); // returns Query
query.findOneAndUpdate(update); // returns Query
query.findOneAndUpdate(callback); // executes
query.findOneAndUpdate(); // returns Query
example 2 :
return TodoModel.findOneAndUpdate({ subject: 'ㅇ' }, { content: 'testtttt' }, { new: true });
조건에 맞는 처음 찾은 데이터의 content 내용을 'testtttt'로 변경 - $set 옵션 없이도 해당 field만 수정됨!
Query.prototype.geometry()
Specifies a $geometry condition
geometry() 는 반드시 intersects() 또는 within() 뒤에 사용되어야 한다.
Parameters :
* object <<object>> Must contain a type property which is a String and a coordinates property which is an Array
Returns :
* <<Query>> this
Query.prototype.get()
업데이트(수정) 시, $set 사용한 value값을 반환한다.
For update operations, returns the value of a path in the update's $set. Useful for writing getters/setters that can work with both update operations and save()
Parameters :
* path <<String | Object>> path or object of key/value pairs to get
Returns :
* <<Query>> this
example :
const query = TodoModel.updateOne({ subject: '테스트' }, { $set: { subject: '뉴젭목' } });
await query.exec(); // 요 쿼리를 실행시켜주어야 subject가 변경됨!!
return query.get('subject'); // 요건 쿼리를 실행시키는 것 없이 그냥 get만 해오는 매서드
returned value :
Query.prototype.getFilter()
현재 쿼리의 filter ( = conditions) 을 POJO로 반환한다.
* POJO = Plain Old JavaScript Object
Parameters :
* nothing
Returns :
* <<Object>> current query filter
example :
const query = TodoModel.find({ subject: '테스트' }).where('startDate').gte('2020-01-01');
return query.getFilter();
returned value :
Query.prototype.getOptions()
쿼리의 옵션을 반환한다.
Parameters :
* nothing
Returns :
* <<Object>> the options
example :
const query = TodoModel.find({ subject: '테스트' }).limit(2).setOptions({ maxTimeMS: 1000 });
return query.getOptions();
returned value :
filter가 아닌 옵션 반환
Query.prototype.getPopulatedPaths()
Gets a list of paths to be populated by this query
Parameters :
* none
Returns :
* <<Array>> an array of strings representing populated paths
example :
Query.prototype.getQuery()
getfileter와 비슷하게 쿼리의 필터를 반환한다.
* getQuery는 곧 사라질 수도 있어서 getFilter()사용을 권함
Parameters :
* none
Returns :
* <<Object>> current query filter
example :
const query = TodoModel.find({ subject: '테스트' }).where('startDate').gt('2020-01-01');
return query.getQuery();
returend value :
Query.prototype.getUpdate()
쿼리의 업데이트 활동을 Json object로 반환한다.
Parameters :
* none
Returns :
* <<Object>> current update operations
example :
const query = TodoModel.updateOne({ subject: '테스트' }, { $set: { subejct: '수정2' } });
return query.getUpdate();
returned value :
query 실행 후 getUpdate()의 결과
const query = TodoModel.updateOne({ subject: '테스트' }, { $set: { subject: '수정2' } });
await query.exec();
return query.getUpdate();
Query.prototype.gt()
Specifies a $gt query condition
When called with one argumetn, the most recent path passed to where() is used.
Parameters :
* [path] <<String>>
* value <<Number>>
example :
return TodoModel.find().where('startDate').gt('2020-01-01');
or
return TodoModel.find().gt('startDate', '2020-01-01');
Query.ptototype.gte()
Specifies a $gte query condition
When called with one argumetn, the most recent path passed to where() is used.
Parameters :
* [path] <<String>>
* value <<Number>>
example :
return TodoModel.find().where('startDate').gt('2020-01-01');
or
return TodoModel.find().gte('startDate', '2020-01-01');
Query.prototype.hint()
Sets query hints
특정 인덱스가 효과있는지 테스트할 때 사용
* distinct()와 함께 쓰일 수 없다
Parameters :
* value <<Object>> a hint object
Returns :
* <<Query>> this
example :
const query = TodoModel.find();
return query.hint({ isDone: 1 });
Query.prototype.in()
Specifies an $in query condition
두번째 인자값, array안의 요소가 있다면
When called with one argument, the most recent path passed to where() is used.
Parameters :
* [path] <<String>>
* value <<Array>>
example :
return TodoModel.find().where('subject', ['테스트', 'ㅇ']);
or
return TodoModel.find().in('subject', ['테스트', 'ㅇ']);
Query.prototype.intersects()
Declares an intersects query for geometry()
* 반드시 where() 이후에 사용되어야 함
Parameters :
* [arg] <<Object>>
Returns :
* <<Query>> this
example :
Query.prototype.j()
Requests acknowledgement that this operation has been persisted to MongoDB's on-disk journal
defaults to the schema's writeConcern.j option
Parameters :
* value <<boolean>>
Returns :
* <<Query>> this
This option is only valid for operations that write to the database
* deleteOne()
* deleteMany()
* findOneAndDelete()
* findOneAndReplace()
* findOneAndUpdate()
* remove()
* update()
* updateOne()
* updateMany()
Query.prototype.lean()
sets the lean option
return plain JS Objects, not Mongoose Documents. They have no save method, getters/setters, virtuals, or other Mongoose features.
결과값을 무거운 몽구스 도큐먼트가 아닌 POJO로 반환
lean은 high-performance, 읽기 전용, 특히 cursors과 결합되된 경우에 좋다.
Parameters :
* bool <<Boolean | Object>> defaults to true
Returns :
* <<Query>> this
example :
const aa = await TodoModel.find().lean();
return aa[0] instanceof mongoose.Document;
Query.prototype.lt()
= less than
Specifies a $lt query condition
When called with one argument, the most recent path passed to where() is used.
Parameters :
* [path] <<String>>
* value <<Number>>
Query.prototype.lte()
= than than or equal
Specifies a $lte query condition
When called with one argument, the most recent path passed to where() is used.
Parameters :
* [path] <<String>>
* value <<Number>>
example :
return TodoModel.find().where('finishDate').lte('2050-01-01');
or
return TodoModel.find().lte('finishDate', '2050-01-01');
Query.prototype.map()
Runs a function fn and treats the return value of fn as the new value for the queryto resolve to.
any functions you pass to map() will run after any post hooks.
Parameters :
* fn <<Function>> function to run to transform the query result
Returns :
* <<Query>> this
Query.prototype.maxDistance()
Specifies a maxDistance query condition
$near or $nearSphere query의 결과를 특정 거리로 제한한다.
When called with one argument, the most recent path passed to where() is used.
Parameters :
* [path] <<String>>
* value <<Number>>
Query.prototype.maxScan()
더이상 사용되지 않음 in the mongo Shell since v3.2
cursor.maxScan() mongoDB 매서드도 사용안함 since v4.0
----> use cursor.maxTimeMS()
Query.prototype.maxTimeMS()
Sets the maxTimeMS option.
mongoDB서버에게 해당 쿼리 실행 시간이 ~milliseconds보다 더 많이 소요되면 끄냥 끝내라고 말함
query.maxTimeMS(v) === query.setOptions({ maxTimeMS: v})
Parameters :
* [ms] <<Number>> The number of milliseconds
Returns :
* <<Query>> this
example :
return TodoModel.find({ subject: '테스트', isDeleted: false }).maxTimeMS(0.0);
Query.prototype.merge()
또 다른 쿼리 or 조건객체를 하나로 합친다
Merges another Query or conditions object into this one.
When a Query is passed, conditions, field selection and options are merged.
Parameters :
* source <<Query | Object>>
Returns :
* <<Query>> this
Query.prototype.mod()
Specifies a $mod condition.
filters documents for documents for documents whose path property is a number that is equal to remainder modulo divisor.
field값이 number인 경우 주어지는 나누는 값으로 나눠 나머지가 설정한 값과 같은 데이터를 반환
Parameters :
* [path] <<String>>
* value <<Array>> must be of length 2, first element is divisor, 2nd element is remainder.
=> [ divisor(나누는 값), remainder(나머지) ]
Returns :
* <<Query>> this
example :
Query.prototype.model
해당 쿼리와 연관되어있는 모델
Type:
* <<property>>
example :
const q = MyModel.find();
q.model === MyModel;
Query.ptototype.mongooseOptions()
getter/setter around the current monoose-specific options for this query Below are the current Mongoose-specific options.
* populate
* lean
* strict
* strictQuery
*nearSphere
Mongoose 는 internal options를 위한 별개의 객체를 유지한다. 왜냐하면 Mongoose는 Query.prototype.options를 MongoDB 서버에 보내고 그리고 위의 option들은 MongoDB 서버와 관련이 없다.
Parameters :
* options <<Object>> if specified, overwrites the current options
Returns :
* <<Object>> the options
Query.prototype.ne()
= not equal
Specifies a $ne query condition
같지않은 value 찾을 때 사용
When called with one argument, the most recent path passed to where() is used.
Parameters :
* [path] <<String>>
* value <<any>>
example :
return TodoModel.find({ content: { $ne: '몽고라니ㅣ' } });
content field 중 '몽고라니ㅣ'가 아닌 데이터를 조회
Query.prototype.near()
These operators return documents sorted by distance
Parameters :
* [path] <<String>>
* value <<Object>>
Returns :
* <<Query>> this
example :
Query.prototype.nearSphere()
더이상 사용하지 않음, use query.near() instead with spherical option set to true.
spherical option을 true로 설정한 near()을 사용하세요
Query.prototype.nin()
= not in
Specifies an $nin query condition
When called with one argument, the most recent path passed to where() is used.
Parameters :
* [path] <<String>>
* value <<Array>>
example :
return TodoModel.find({ subject: { $nin: ['테스트', '몽고라니ㅣ', 'get test '] } });
subject가 ['테스트', '몽고라니ㅣ', 'get test '] 배열 안에 없는 것들만 조회
example2 :
위의 Query.prototype.in() 과 함께 사용해보기
return TodoModel.find({
subject: { $nin: ['테스트', '몽고라니ㅣ', 'get test '] },
content: { $in: ['수정22'] },
});
Query.prototype.nor()
Specifies arguments for a $nor condition
주어진 배열에 있는 조건들 중 하나라도 fail 하는 데이터가 있다면 제외 (주어진 조건 중 하나라도 fail하지 않는 데이터만 조회)
Parameters :
* array <<Array>> array of conditions
Returns :
* <<Query>> this
example :
return TodoModel.find().nor([{ subject: '테스트' }, { content: '수정22' }]);
subject가 '테스트'도 아니고 content가 '수정22'도 아닌 데이터 조회
Query.prototype.or()
Specifies arguments for an $or condition
주어진 배열 안의 조건들 중 하나라도 충족하는 데이터 조회
Parameters :
* array <<Array>> array of conditions
Returns :
* <<Query>> this
example :
return TodoModel.find().or([{ subject: '테스트' }, { content: '테스트' }]);
-> subject === '테스트' 이거나 또는 content === '테스트'인 데이터 조회
Query.prototype.orFail()
만약 주어진 필터에 맞는 데이터가 없으면 에러를 내도록 만든다. async/await와 통합하기에 편리하다 왜냐하면 orFail()은 if 절 하나를 줄일 수 있기 때문이다.
Parameters :
* [err] <<Function | Error>> optional error to throw if no docs match filter. If not specified, orFail()will throw a DocumentNotFoundError
Returns :
* <<Query>> this
example :
return TodoModel.findOne({ subject: 'asdf' }).orFail();
or
return TodoModel.updateOne({subject:'asdf'}, {content:'asdf'}).orFail();
returned value :
Query.prototype.polyfon()
Specifies a $polygon condition
Parameters :
* [path] <<String | Array>>
* [coordinatePairs...] <<Array | Object>>
Returns :
* <<Query>> this
example :
Query.prototype.populate()
Specifies paths which should be populated with other documents.
도큐먼트를 덧붙여 함께 불러오기
자동으로 도큐먼트의 특정한 path에 다른 콜렉션에서 불러온 도큐먼트를 대체하는 것
Schema 에 type: Schema.Types.ObjectId; 설정 + ref: '속한 모델명' 추가하기
Parameters :
* path <<Object | String>> either the path to populate or an object specifying all parameters
* [select] <<Object | String>> Field selection for the population query
* [model] <<Model>> The model you wish to use for population. If not specified, populate will look up the model by the name in the Schema's ref field.
* [match] <<Object>> Conditions for the population query
* [options] <<Object>> Options for the population query (sort, etc)
options | |
[options.path=null] <<String>> | The path to populate |
[options.retainNullValues=false] <<boolean>> | by default, Mongoose removes null and undefined values from populated arrays. Use this options to make populate() retain null and undefined array entries. |
[options.getters=false] <<boolean>> | if true, Mongoose will call any getters defined on the localField. By default, Mongoose gets the raw value of localField. For example, you would need to set this option to true if you wanted to add a lowercase getter to your localField. |
[options.clone=false] <<boolean>> | When you do BlogPost.find().populate('author'), blog posts with the same author will share 1 copy of an author doc. Enable this option to make Mongoose clone populated docs before assigning them. |
[options.match=null] <<Object | Functoin >> | Add an additional filter to the populate query. Can be a filter object containing MongoDB query syntax, or a function that returns a filter object. |
[options.transform=null] <<Function>> | Function that Mongoose will call on every populated document that allows you to transform the populated document. |
[options.options=null] <<Object>> | Additional options like limit and lean. |
Returns :
* <<Query>> this
example : https://dev.to/paras594/how-to-use-populate-in-mongoose-node-js-mo0
example 2:
todo list Schema
- populate 연습위해 댓글들을 배열로 모은 comments라는 collection을 수작업으로 만듬
import { Schema, Document, Model } from 'mongoose';
import database from '../../config/database/mongoDB/mongodb.connect';
export interface ITodoComment extends Document {
contents: string;
createdAt: Date;
}
export interface ITodo extends Document {
id: Schema.Types.ObjectId;
subject: string;
content: string;
startDate: Date;
finishDate: Date;
isDone: boolean;
isDeleted: boolean;
comments?: ITodoComment[];
createdAt: Date;
updatedAt: Date;
deletedAt: Date;
}
export interface IComments extends Document {
contents: string;
todoId: Schema.Types.ObjectId;
}
const CommentsSchema: Schema = new Schema(
{
contents: { type: String },
todoId: { type: Schema.Types.ObjectId, ref: 'todo' },
},
{
_id: true,
timestamps: { createdAt: true, updatedAt: false },
versionKey: false,
},
);
const CommentSchema: Schema = new Schema(
{
// 댓글
contents: { type: String, required: true },
},
{
// subDoc 에는 _id: true 가 default 값
_id: true,
timestamps: { createdAt: true, updatedAt: false },
versionKey: false,
},
);
const TodoSchema: Schema<ITodo> = new Schema<ITodo>(
{
// 할일 제목
subject: { type: String, required: true },
// 할일 내용
content: { type: String, required: true },
// 시작 날짜
startDate: { type: Date, required: true },
// 마감 날짜
finishDate: { type: Date, required: true },
// 완료 여부
isDone: { type: Boolean, default: false },
// 삭제 여부
isDeleted: { type: Boolean, default: false },
// 댓글
comments: [CommentSchema],
// 삭제 날짜
deletedAt: { type: Date },
},
{
timestamps: true,
read: 'secondaryPreferred',
skipVersioning: true,
versionKey: false,
},
);
const TodoModel: Model<ITodo> = database.model<ITodo>('todo', TodoSchema, 'todo');
export const CommentsModel: Model<IComments> = database.model<IComments>('comments', CommentsSchema, 'comments');
export default TodoModel;
Query :
return CommentsModel.find().populate('todoId');
returned value :
example 3 :
* populate해온 도큐먼트에서 원하는 fields를 선택해오기
return CommentsModel.find().populate('todoId', 'subject content');
returned value :
example 4:
return TodoModel.find().populate('commentIds');
returned value :
Query.prototype.post()
해당 쿼리 인스턴스에 post 미들웨어를 추가한다(더한다). 다른 쿼리들에게 영향을 미치지 않는다.
Add post middleware to this query instance. Doesn't affect other queries.
Parameters :
* fn <<Function>
Returns :
* <<Promise>>
example :
const q = TodoModel.find({ subject: '테스트' });
q.post(function middleware() {
console.log(this.getFilter());
});
return q.exec();
-> console에 찍히는 값
{subject: '테스트'}
Query.prototype.pre()
해당 쿼리에 pre middleware를 추가한다. 다른 쿼리들에게 영향을 미치지않는다.
Add pre middleware to this query instance. Doesn't affect other queries.
Parameters :
* fn <<Function>>
Returns :
* <<Promise>>
example :
const q = TodoModel.find({ subject: '테스트' });
q.pre(function middleware() {
console.log(this.getFilter());
});
return q.exec();
-> console에 찍히는 값
{subject: '테스트'}
Query.prototype.projection()
Get/set the current projection (AKA fields). Pass null to remove the current projection.
projection()과 다르게 select()은 현재 제 자리에 있는(가동 중인) projection을 수정시킨다.
Unlike projection(), the select() function modifies the current projection in place. This function everwrites the existing projection.
Parameters :
* arg <<Object | null>>
Returns :
* <<Object>> the current projection
example :
?? projection을 언제 써야하는거지
Query.prototype.read()
Determines the MongoDB nodes from which to read.
p에 (쓰기) 써지고 s로 전파되는 시간이 꽤 걸릴 때 s로 부터 이전 데이터를 읽어오게 될 수도 있음 -> 이 때 읽기 p로 지정해주는 것
* mongo atlas - replica lack 복제 지연시간
Parameters :
* pref <<String>> one of the listed preference options or aliases
* [tags] <<Array>> optional tags for this query
Returns :
* <<Query>> this
Preferences :
Preferences | |
primary (default) | primary부터 오직 읽는다. 만약 primary를 이용할 수 없다면 에러가 난다. Read from primary only. Operations will produce an error if primary is unavailable. Cannot be combined with tags. |
secondary | secondary부터 읽고 가능하지 않다면 에러 Read from secondary if available, otherwise error. |
primaryPreferred | primary부터 읽고, 여의치 않은 경우 secondary를 읽는다. Rad from primary if available, otherwise a secondary. |
secondaryPreferred | secondary부터 읽고, 여의치 않은 경우 primary를 읽는다. Read from a secondary if available, otherwise read from the primary. * mongoDB가 보통 primary를 주로 씀 (쓰기), 부하 막기위해 읽기는 요 옵션으로 먼저 줌 |
nearest | 가장 가까운 후보자부터 읽는다. primary, secondary 구분하지 않는다. All operations read from among the nearest candidates, but unlike other modes, this option will include both the primary and all secondaries in the random selection. |
Aliases :
Aliases | |
p | primary |
pp | primaryPreferred |
s | secondary |
sp | secondaryPreferred |
n | nearest |
??
primary 와 secondary 가 무엇인가,,,, -> 몽고디비는 db 인스턴스 기본적으로 3개가 떠있음 -> 투표때문에 보통 홀수로 -> 투표로 p, s 를 부하따라서 알아서 설정함.
Query.prototype.readConcern()
Sets the readConcern option for the query.
Parameters :
* level <<String>> one of the listed read concern level or their aliases
Returns :
* <<Query>> this
example :
Query.prototype.regex()
Specifies a $regex query condition
when called with one argumetn, the most recent path passed to where() is used.
Parameters :
* [path] <<String>>
* value <<String | RegExp>>
example :
if (_.isEmpty(searchWord) === false) {
const regex: object = new RegExp(searchWord, 'g');
query.$or = [{ subject: { $regex: regex } }, { content: { $regex: regex } }];
}
Query.prototype.remove()
remove()는 더이상 사용되지 않으므로 deleteOne()을 사용하기
This function does not trigger any middleware
Parameters :
* [filetr] <<Object | Queyr>> mongodb selector
* [callback] <<Function>> optional params are (error, mongooseDeleteResult)
Returns :
* <<Query>> this
Query.prototype.replaceOne()
update()와 비슷하다. 존재하는 하나의 도큐먼트를 모두 수정(대체)한다. 이 때, update()와 다른 점은 $set 등과 같은 부분 수정이 불가하다는 점이다.
Declare and/or execute this query as a replaceOne() operation. Same as update(), except MongoDB will replace the existing document and will not accept any atomic operators ($set, etc.).
Parameter :
* [filter] <<Object>>
* [doc] <<Object>> the update command
* [options] <<Object>>
Options | |
[options.multipleCastError] <<Boolean>> | by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors. mongoose는 발생한 에러 중 첫번째 에러만 반환하는데 이 옵션을 true로 하면 모든 에러들을 통합한다. |
[options.strict] <<Boolean | String>> | overwrites the schema's strict mode option * strict option : The strict option, (enabled by default), ensures that values passed to our model constructor that were not specified in our schema do not get saved to the db. |
[options.upsert=false]<<Boolean>> | if true, and no documents found, insert a new document true일 경우에 찾아지는 도큐먼트가 없다면 새로운 도큐먼트로 추가한다. |
[options.writeConcern=null] <<Object>> | sets the write concern for replica sets. Overrides the schema-level write concern |
[options.timestamps=null]<<Boolean>> | If set to false and schema-level timestamps are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set 해당 옵션이 false로 되어있고 schema-level timestamps가 활성화 되어 있다면 업데이트를 위한 timestamps를 skipgksek. 만약 schema-level timestamps가 설정되어 있지 않다면 아무런 일도 안일어난다. |
example :
const res = await TodoModel.replaceOne({ subject: '24' }, {});
console.log(res.n); // undefined
console.log(res.nModified); // undefined
console.log(res.matchedCount); // 1
console.log(res.modifiedCount); // 1
return res;
공식문서에 나온 n, nModified는 undefined로 나온다 !
returned value :
With replaceOne() you can only replace the entire document, while updateOne() allows for updating fields. Since replaceOne() replaces the entire document - fields in the old document not contained in the new will be lost. With updateOne() new fields can be added without losing the fields in the old document.
replaceOne()을 실행하면 새로운 도큐먼트에 없는 필드들은 사라진다.
??
남은 필드값 :
_id, isDone, isDeleted, updatedAt, createdAt, comments
-> _id, updatedAt, createdAt은 이해가 되는데 왜 나머지 필드들은 사라지지않았지?? subject, content, startDate, finishDate는 없음.
Query.prototype.select()
Specifies which document fields to include or exclude (also known as the query 'projection')
어떤 도큐먼트의 필드를 포함할지, 제외할지 정한다.
string syntax를 사용하여 ' - ' 와 함께 prefixing a path 를 하면 그 path를 배제했다고 할 것이다. a path가 ' - '를 가지지 않은 경우 포함된다. 그리고 만약 a path가 ' + '와 prefixed되었다면 이는 the path를 강제 포함시킨다.
string syntax 가 - 와 함께 쓰이면 -> 배제, -가 쓰이지 않으면 -> 포함, +와 함께 쓰이면 -> 포함
** - & + 를 함께 쓸 수 없다. -> _id는 예외 (mongoDB는 디폴트값으로 _id를 항상 포함시키기때문)
When using string syntax, prefixing a path with - will flag that path as excluded. When a path does not have the - prefix, it is included. Lastly, if a path is prefixed with +, it forces inclusion of th path, which is useful for paths excluded at the schema level.
Parameters :
* arg <<Object | String | Array<String> >>
Returns :
* <<Query>> this
example :
return TodoModel.find().select('subject content');
returned value :
example2 :
return TodoModel.find().select('-subject -content');
returned value :
ERROR ! include + exclude 함께 쓰면 에러가 난다
return TodoModel.find().select('-subject -content isDeleted');
returned Error :
Query.prototype.selected()
field 선택이 되었는지 아닌지 체크한다.
Returns :
* <<Boolean>>
example :
const q = TodoModel.find().select('-subject -content isDeleted');
return q.selected();
returned value :
true
example2 :
const q = TodoModel.find();
return q.selected();
returned value :
postman이 계속 ing 으로 뜸. 에러 !
Query.prototype.selectedExclusively()
필드 배제하는 선택이 쿼리에 추가되었는지 체크한다. (fields 여러개 배제해도 상관없음)
Determines if exclusive field selection has been made.
Returns :
* <<Boolean>>
example :
const q = TodoModel.find().select('-subject content');
return q.selectedExclusively();
returned value :
true
Query.prototype.selectedInclusively()
필드 포함하는 선택이 쿼리에 추가되었는지 체크한다.
Returns :
* <<Boolean>>
example :
const q = TodoModel.find().select('content _id');
return q.selectedInclusively();
returned value :
true
Query.prototype.session()
Sets the mongoDB session associated with this query. Sessions are how you mark a query as part of a transaction.
Calling session(null) removes the session from this query.
* transaction : 독자적으로 여러개의 operations를 실행하다가 만약 하나라도 실패를 하면 잠재적으로 모든 operations를 되돌린다.
Parameters :
* [session] <<ClientSession>> from await conn.startSession()
Returns :
* <<Query>> this
example :
const s = await mongoose.startSession();
return TodoModel.findOne({ subject: 'upsert' }).session(s);
?? return이 안된당
Query.prototype.set()
다른 fields는 변경시키지않고 해당 쿼리의 수정만 하도록 한다. 이는 쿼리 미들웨어에게 유용해서 updateOne(), updateMany(), findOneAndUpdate() 등 어떤 매서드를 쓰든 update를 추가할 수 있다.
Adds a $set to this query's update without changing the operation. This is useful for query middleware so you can add an update regardless of whether you use updateOne(), updateMany(), findOneAndUpdate(), etc.
example :
return TodoModel.updateOne({ subject: 'upsert' }, {}).set('content', 'set사용해서바꿈');
returned value :
Query.ptototype.setOptions()
Sets query options. Some options only make sense for certain operations.
Parameters :
* options <<Object>>
Returns :
* <<Query>> this
Options :
find() 와 함께 쓸 수 있는 옵션들 | |
tailable | |
sort | |
limit | |
skip | |
allowDistUse | |
batchSize | |
readPreference | |
hint | |
comment | |
snapshot | |
maxscan | |
write operations 와 함께쓰는 옵션들 ex. update(), updateOne(), updateMany(), replaceOne(), findOneAndUpdate(), findByIdAndUpdate() |
|
upsert | |
writeConcern | |
timestamps | |
omitUndefined | |
overwriteDiscriminatorKey | |
find(), findOne(), findById(), findOneAndUpdate(), findByIdAndUpdate() | |
lean | |
populate | |
projection | |
sanitizeProjection | |
아래 매서드들을 제외하고 모든 operations와 사용할 수 있다. | |
maxTimeMS | |
fineOneAndUpdate(), findOneAndRemove()와 함께쓰는 옵션 | |
rawResult | * lean으로 대체 |
모든 operations와 함께 사용할 수 있는 옵션 | |
strict | |
collation | |
session | |
explain |
example :
Query.prototype.setQuery()
Sets the query conditions to the provided JSON object
Parameters :
* new <<Object>> query conditions
Returns :
* <<undefined>>
example :
const q = TodoModel.find({subject: 'upsert'});
console.log(q.getQuery()); // {subject: 'upsert'}
return q;
returned value : {subject: 'upsert'} 가 적용된 데이터 조회됨
example 2 :
const q = TodoModel.find({subject:'upsert'});
q.setQuery({ content: '연습' });
console.log(q.getQuery()); // { content: '연습'}
return q;
returned value : {content: '연습'} 이 적용된 데이터 조회됨
Query.prototype.setUpdate()
set 설정값 수정하기
Sets the current update operation to new value.
Parameters :
* new <<Object>> update operation
Returns :
* <<undefined>>
example :
const q = TodoModel.find();
q.update({ subject: 'upsert' }, { $set: { content: 'aaa' } }, { limit: 5 });
q.setUpdate({ $set: { content: 'bbb' } });
console.log(q.getFilter());
console.log(q.getQuery());
console.log(q.getUpdate());
console.log(q.getOptions());
return q.getUpdate();
returned console.log
{ subject: 'upsert' }
{ subject: 'upsert' }
{ '$set': { content: 'bbb' } }
{ limit: 5 }
returned value :
* setUpdate() 매서드로 업데이트 된 값이 나옴 !
Query.prototype.size()
Specifies a $size query condition.
특정 field array의 길이가 n이상 되는 document들을 검색하고 싶을 때 size()를 사용한다. range(범위)를 사용할 수 없고 정확하게 매칭되는 하나의 숫자만 검색할 수 있다.
When called with one argument, the most recent path passed to where() is used.
Parameters :
* [path] <<String>>
* value <<Number>>
example :
comments filed 배열 값 안에 요소가 정확하게 2개인 데이터들을 불러오기
const docs = await TodoModel.where('comments').size(2).exec();
//assert(Array.isArray(docs)); // 요건 왜 하는건지 아직 모르겟다 !
console.log(docs);
return docs;
** comments field의 배열 안 요소들의 개수가 정확하게 2개인 것들만 조회해온다.
Query.prototype.skip()
Specifies the number of documents to skip
스킵할 도큐먼트의 수를 설정한다. (pagination에서 많이 사용)
* cannot be used with distinct() / distinct 와 사용될 수 없다.
Parameters :
* val <<Number>>
example :
return TodoModel.find().skip(2).limit(5);
최대 5개를 조회해온 데이터 -> 조회할 때 시작점은 첫 데이터가 아닌 skip(2)이므로 6번째부터 조회해온다.
skip(1)일 경우, 처음부터 조회, skip(2)일 경우에는 limit 만큼의 수를 더한 값부터 조회 (db는 index 0 부터 시작이므로 -1)
skip | limit | 조회해오는 데이터 index |
1 | 5 | 0~4 |
2 | 5 | 5~9 |
Query.prototype.slaveOk()
더이상 사용되지 않는다.
Query.prototype.slice()
배열의 요소를 주어진 number만큼 반환
Specifies a $slice projection for an array.
Parameters :
* [path] <<String>>
* value <<Number>> number/range of elements to slice
-> 가져올 개수만 넣는다면 바로 number로 넣고 ~번째부터 가져올 개수를 넣는다면 배열로 넣기
(첫번째 인자값 : 시작 인덱스, 두번째 인자값 : 가져올 개수)
Returns :
* <<Query>> this
example :
return TodoModel.find().slice('comments', 1);
return TodoModel.find().slice('comments', -1); // 끝에서 첫번째 요소
return TodoModel.find({ subject: '검색' }).slice('comments', [1, 2]); // 1번째부터 2개의 데이터 가져오기 (1번째 = 두번째 index)
return TodoModel.find({ subject: '검색' }).where('comments').slice(2);
return TodoModel.find({ subject: '검색' }).where('comments').slice([1, 2]);
Query.prototype.snapshot()
back up할 때 mongoDB snapshot()이라는 걸 사용하는 것 같다.
Specifies this query as a snapshot query.
* cannot be used with distinct() / distinct 와 사용될 수 없다.
Returns :
* <<Query>> this
example :
Query.prototype.sort()
Sets the sort order
전달되는 데이터가 객체 an Object 일 때 사용가능한 values는 asc, desc, ascending, descending, 1, -1 이 있다.
만약 string이 전달되면 path names의 리스트의 범위를 정해주는 space이어야 한다. 이 때 각각의 path의 sort order는 ' - ' 마이너스를 앞에 붙여주지 않는이상 오름차순이다.
If an object is passed, values allowed are asc, desc, ascending, descending, 1, and -1.
If a string is passed, it must be a space delimited list of path names. The sort order of each path is ascending unless the path name is prefixed with - which will be treated as descending.
Parameters :
* arg <<Object | String >>
Returns :
* <<Query>> this
example :
return TodoModel.find().sort({ subject: 'desc' });
or
return TodoModel.find().sort('subject -content');
or
return TodoModel.find().sort({ subject: 1 });
Query.prototype.tailable()
Sets the tailable option (for use with capped collections)
Parameters :
* bool <<Boolean>> defaults to true
* [opts] <<Object>> options to set
options | |
[opts.numberOfRetries] <<Number>> | if cursor is exhausted, retry this many times before giving up |
[opts.tailableRetryInterval] <<Number>> | if cursor is exhausted, wait this many milliseconds before retrying |
example :
Query.prototype.then()
resolved 되었거나 rejected 된 결과를 Promise로 반환하는 쿼리를 실행한다.
Executes the query returning a Promise which will be resolved with either the doc(s) or rejected with the error.
Parameters :
* [resolve] <<Function>>
* [reject] <<Function>>
Returns :
* <<Promise>>
example :
Query.prototype.toConstructor()
모든 arguments와 옵션을 유지한채, 해당 쿼리를 맞춤형으로, 재사용 가능한 construtor로 바꾼다.
Converts this query to a customized, reusable query constructor with all arguments and options retained.
Returns :
* <<QUery>> subclass-of-Query
example :
Query.prototype.update()
수정하는 매서드
만약 도큐먼트의 필드들을 부분적으로 수정하고 싶다면 $set을 사용하면 된다.
Declare and/or execute this query as an update() operation.
All paths passed that are not atomic operations will become $set ops.
This function triggers the following middleware
* update()
Valid Options :
Valid Options : | |
upsert (boolean) | whether to create the doc if it doesn't match (false) |
multi (boolean) | whether multiple documents should be updated (false) |
runValidators (boolean) | if true, runs update validators on this command. Update validators validate the update operation against the modle's shema |
setDefaultsOnInsert (boolean) | true by default. If setDefaultsOnInsert and upsert are true, mongoose will apply the defaults specified in the modle's shcema if a new document is created |
strict (boolean) | overrides the strict option for this update |
read | |
writeConcern |
Parameters :
* [filter] <<Object>>
* [doc] <<Object>> the update command
* [options] <<Object>>
options | |
[options.multipleCastError] <<Boolean>> | by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors. |
[options.strict] <<Boolean | String>> | overwrites the schema's strict mode option |
[options.upsert=false] <<Boolean>> | if true, and no documents found, insert a new document |
[options.writeConcern=null] <<Object>> | sets the write concern for replica sets. Overrides the schema-level write concern |
[options.timestamps=null] <<Boolean>> | If set to false and schema-level timestamps are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set |
* [callback] <<Function>> params are (error, writeOpResult)
Returns :
* <<Query>> this
API summary :
update(filter, doc, options, callback); // executes
update(filter, doc, options);
update(filter, doc, callback); // executes
update(filter, doc);
update(doc, callback); // executes
update(doc);
update(callback); // executes
update(true); // executes
update();
example :
return TodoModel.find()
.where({ _id: '6191f159b0f6940f5994abab' })
.update({ $set: { subject: 'update로 변경한 주제' } });
returned value :
{
"acknowledged": true,
"modifiedCount": 1,
"upsertedId": null,
"upsertedCount": 0,
"matchedCount": 1
}
* 만약 수정할 내용이 {} 라면 update opertaion은 무시되지만 callback은 mongoDB로 명령어 전달을 안하고 실행된다.
The operation은 오직 callback이 전달될 때에만 실행된다. callback없이 강제로 실행시키기 위해서는 우리는 반드시 update()를 먼저 호출하고 그 다음에 exec()매서드를 이용해서 실행해야 한다.
Query.prorotype.updateMany()
한번에 많은 수의 도큐먼트를 수정할 때 사용하는 매서드
Declare and/or execute this query as an updateMany() operation. Same as update(), except MongoDB will update all documents that match filter (as opposed to just the first one) regardless of the value of the muliti option.
updateMany()는 update 미들웨어를 일으키지 않는다. 대신 pre('updateMany) and post('updateMany')를 사용하면 된다.
* 부분적으로 수정하고 싶다면 update()매서드처럼 $set을 사용하면 된다.
Parameters :
* [filter] <<Object>>
* [doc] <<Object>> the update command
* [options] <<Object>>
options | |
[options.multipleCastError] <<Boolean>> | by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors. |
[options.strict] <<Boolean | String>> | overwrites the schema's strict mode option |
[options.upsert=false] <<Boolean>> | if true, and no documents found, insert a new document |
[options.writeConcern=null] <<Object>> | sets the write concern for replica sets. Overrides the schema-level write concern |
[options.timestamps=null] <<Boolean>> | If set to false and schema-level timestamps are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set |
* [callback] <<Function>> params are (error, writeOpResult)
Returns :
* <<Query>> this
Query.prototype.updateOne()
하나의 도큐먼트 내용만 수정한다. 이 역시 $set이 필요하다. 전체 도큐먼트를 다 바꾸는 경우에는 replaceOne()을 사용하면 된다.
MongoDB는 multi option의 값과 상관없이 한 조건에 맞는 첫번째 데이터를 반환한다.
Parameters :
* [filter] <<Object>>
* [doc] <<Object>> the update command
* [options] <<Object>>
options | |
[options.multipleCastError] <<Boolean>> | by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors. |
[options.strict] <<Boolean | String>> | overwrites the schema's strict mode option |
[options.upsert=false] <<Boolean>> | if true, and no documents found, insert a new document |
[options.writeConcern=null] <<Object>> | sets the write concern for replica sets. Overrides the schema-level write concern |
[options.timestamps=null] <<Boolean>> | If set to false and schema-level timestamps are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set |
* [callback] <<Function>> params are (error, writeOpResult)
Returns :
* <<Query>> this
example :
return TodoModel.find().updateOne(
{ _id: '6191f159b0f6940f5994abab' },
{ $set: { subject: 'updateOne으로 수정22' } },
);
returned value :
?? set을 해도 안해도 왜 똑같이 해당 field만 바뀌는 것이지,,,, ?
example 2 : (using $setOnInsert - upsert:true일 경우, Insert실행이되면 $setOnInsert 내용이 처리되고 insert가 아닌 update일 경우 (첫 데이터 입력이 아닌경우) 에는 $setOnInsert는 아무 것도 하지 않음 )
const aa = async (year, month, holidays) => {
return HolidayModel.updateOne(
{ year, month },
{ $setOnInsert: { year, month }, $set: { holidays } },
{ upsert: true, lean: true },
);
};
Query.prototype.use$geoWithin
flag to opt out of using $geoWithin
Type :
* <<property>>
* MongoDB 2.4 deprecated the use of $within, replacing it with $geoWithin. Mongoose uses $geoWithin by default (which is 100% backward compatible with $within). If you are running an older version of MongoDB, set this flag to false so your within() queries continue to work.
Query.prototype.w()
특정한 수의 mongod 서버를 설정한다 or 태그한다.
Sets the specified number of mongod servers, or tag set of mongod servers, that must acknowledge this write before this write is considered successful.
Parameters :
* value <<String | number>> 0 for fire-and-forget, 1 for acknowledged by one server, 'majority' for majority of the replica set, or any of the more advanced options.
Returns :
* <<Query>> this
Query.prototype.where()
path를 정해준다.
Specifies a path for use with chaining.
Parameters :
* [path] <<String | Object>>
* [value] <<any>>
Returns :
* <<Query>> this
example :
return Todomodel.find({ startDate: { $gte: '2020-02-02' });
Query.prototype.within()
Defines a $within or $geoWithin argument for geo-spatial queries.
* MUST be used after where()! 반드시 where() 뒤에 붙여 쓰기
Returns :
* <<Query>>
example :
Query.prototype.writeConcern()
Parameters :
* writeConcern <<Object>> the write concern value to set
Returns :
* <<Query>> this
Query.prototype.wtimeout()
If w > 1, the maximum amount of time to wait for this write to propagate through the replica set before this operation fails. The default is 0, which means no timeout.
Parameters :
* ms <<number>> number of milliseconds to wait
Returns
* <<Query>> this
Bulk Write Operations
db.collection.bulkWrite()
하나의 collection의 대량 db 처리할 때 사용한다.
ordered - (default) 순차적, 하나라도 에러나면 멈춤
정렬된 (ordered) operations의 list로 MongoDB는 일련으로 해당 Operations를 처리한다. 만약 write operations 중 하나에서 에러가 발생했다면 MongoDB는 남은 operations처리를 멈춘채 return한다.
unordered - 무작위, 하나 에러나더라도 진행
무작위의 (unordered) operations의 list로 MongoDB는 병렬적으로 (평행하게) 처리한다. 하지만 이 처리 순서는 무작위이다. operations중 하나가 에러 발생하더라도 MongoDB는 계속해서 나머지 operations 처리를 계속 해나간다.
디폴트값으로 bulkWrite()는 ordered operations를 갖는다. unodered를 하기 위해서는 options를 ordered: false로 해주면 된다.
bulkWrite()와 함께 쓸 수 있는 write operations :
insertOne | updateOne | updateMany | replaceOne | deleteOne | deleteMany |
example 1 :
*** 주의점 *** options: { upsert: true } 가 아니라 바로 upsert: true를 직접 써줘야함 !!!!
try {
db.characters.bulkWrite(
[
{ insertOne :
{
"document" :
{
"_id" : 4, "char" : "Dithras", "class" : "barbarian", "lvl" : 4
}
}
},
{ insertOne :
{
"document" :
{
"_id" : 5, "char" : "Taeln", "class" : "fighter", "lvl" : 3
}
}
},
{ updateOne :
{
"filter" : { "char" : "Eldon" },
"update" : { $set : { "status" : "Critical Injury" } },
"upsert" : true,
}
},
{ deleteOne :
{ "filter" : { "char" : "Brisbane" } }
},
{ replaceOne :
{
"filter" : { "char" : "Meldane" },
"replacement" : { "char" : "Tanys", "class" : "oracle", "lvl" : 4 }
}
}
]
);
}
catch (e) {
print(e);
}
example 2 :
const saveHolidays = async arrayForBulk => {
return HolidayDao.saveHolidays(arrayForBulk);
};
const getHolidayInfo = holidays => {
const preHolidayInfo = [];
.
.
.
return preHolidayInfo;
};
const sendRequest = async (n, date) => {
.
.
.
return {
updateOne: {
filter: { year, month },
update: { $setOnInsert: { year, month }, $set: { holidays } },
upsert: true,
},
};
};
const exec = async () => {
const date = moment();
const n = 12;
const nArray = Array.from(Array(n).keys());
const result = await Promise.all(
nArray.map(async ele => {
return sendRequest(ele, date);
}),
);
return saveHolidays(result);
};
export default {
exec,
};
db.collection.initializeUnorderedBulkOp()
collection에 대량 operations를 처리한다. unordered -> 중간에 오류가 나더라도 계속 진행된다. 순서는 무작위로 mongoDB가 대량으로 처리한다.
const function = async (AAA) => {
const bulk = Model.collection.initializeUnorderedBulkOp();
for (let i = 0; i < AAA.length; i++) {
console.log('i===', i);
bulk.find({ a: 1 }).upsert().updateOne({ b: 1000 });
}
return bulk.execute();
};
returned value :
수정할 내용이 있거나 데이타가 없어서 새로 insert할 때 returned value :
nMatched : 맞는 것이 없고 nModified 때문에 수정한 것도 없음
nUpserted : 새로 추가한게 2개의 데이터
{
"ok": 1,
"writeErrors": [],
"writeConcernErrors": [],
"insertedIds": [],
"nInserted": 0,
"nUpserted": 2,
"nMatched": 0,
"nModified": 0,
"nRemoved": 0,
"upserted": [
{
"index": 0,
"_id": "619de44819b61d42508ba1"
},
{
"index": 1,
"_id": "619de4819b61d432508ba2"
}
]
}
수정할 내용이 없을 때 : nMatched 몇개가 매치되었는지 나오고 수정되거나 추가되는 것이 없음
{
"ok": 1,
"writeErrors": [],
"writeConcernErrors": [],
"insertedIds": [],
"nInserted": 0,
"nUpserted": 0,
"nMatched": 2,
"nModified": 0,
"nRemoved": 0,
"upserted": []
}
db.collection.initializeOrderedBulkOp()
References: https://mongoosejs.com/docs/api/query.html#query_Query
'mongoDB' 카테고리의 다른 글
[mongoDB] Operations (0) | 2021.11.26 |
---|---|
[MongoDB] Replica set이란? (0) | 2021.11.19 |
[MongoDB] options - lean, new, upsert (0) | 2021.11.15 |
[DB] MongoDB Index 개념과 설계 전략 (0) | 2021.11.12 |
[MongoDB] DAS, NAS, SAN, HDD, SSD, 인덱스란? (0) | 2021.11.11 |