mongodb에서 문자열을 숫자 값으로 변환하는 방법
MongoDB의 aggregate query에서 수치가 포함된 문자열을 값으로 변환하려고 합니다.
문서 예제
{
"_id": ObjectId("5522XXXXXXXXXXXX"),
"Date": "2015-04-05",
"PartnerID": "123456",
"moop": "1234"
}
사용하는 집계 쿼리의 예
{
aggregate: 'my_collection',
pipeline: [
{$match: {
Date :
{$gt:'2015-04-01',
$lt: '2015-04-05'
}}
},
{$group:
{_id: "$PartnerID",
total:{$sum:'$moop'}
}}]}
결과가 나온 곳에
{
"result": [
{
"_id": "123456",
"total": NumberInt(0)
}
}
어떻게 문자열을 숫자 값으로 변환할 수 있습니까?
MongoDB 집계는 지정된 필드의 기존 데이터 유형을 변경할 수 없습니다. 이경우드 변 환 생 야 합 니 해 다 성 코string
int
db.collectionName.find().forEach(function(data) {
db.collectionName.update({
"_id": data._id,
"moop": data.moop
}, {
"$set": {
"PartnerID": parseInt(data.PartnerID)
}
});
})
컬렉션 크기가 위 스크립트보다 크면 성능이 저하됩니다. 성능 향상을 위해 mongo bulk 작업 및 업데이트된 데이터 유형을 사용하여 mongo bulk 작업을 제공합니다.
var bulk = db.collectionName.initializeOrderedBulkOp();
var counter = 0;
db.collectionName.find().forEach(function(data) {
var updoc = {
"$set": {}
};
var myKey = "PartnerID";
updoc["$set"][myKey] = parseInt(data.PartnerID);
// queue the update
bulk.find({
"_id": data._id
}).update(updoc);
counter++;
// Drain and re-initialize every 1000 update statements
if (counter % 1000 == 0) {
bulk.execute();
bulk = db.collectionName.initializeOrderedBulkOp();
}
})
// Add the rest in the queue
if (counter % 1000 != 0) bulk.execute();
이렇게 하면 기본적으로 서버에 보내는 작업 명령문의 양이 대기 중인 작업 1000개마다 한 번씩만 전송됩니다.
MongoDB 4.0 이상 사용
두 가지 옵션이 있습니다. 즉, 또는 를 사용하여 다음 예를 따릅니다.
filterDateStage = {
'$match': {
'Date': {
'$gt': '2015-04-01',
'$lt': '2015-04-05'
}
}
};
groupStage = {
'$group': {
'_id': '$PartnerID',
'total': { '$sum': { '$toInt': '$moop' } }
}
};
db.getCollection('my_collection').aggregate([
filterDateStage,
groupStage
])
변환 작업에서 오류가 발생하면 집계 작업이 중지되고 오류가 발생합니다.이 동작을 재정의하려면 대신 를 사용합니다.
사용
groupStage = {
'$group': {
'_id': '$PartnerID',
'total': {
'$sum': {
'$convert': { 'input': '$moop', 'to': 'int' }
}
}
}
};
지도/축소 사용
하면 / 소를사다같음은축과 를 사용할 수 .parseInt()
변환할 수 있습니다.예를 들어, 각 입력 문서를 처리하는 지도 함수를 정의할 수 있습니다. 에서수함,this
맵 편집 작업이 처리 중인 문서를 참조합니다.된 함는변데이매핑다니합을 .moop
을 " " " " "로 지정합니다.PartnerID
각 문서에 대해 그리고 방출합니다.PartnerID
변환된 된환변moop
함수 쌍. 여기자크네이함브수티입니다트립바스가▁pair.parseInt()
적용 가능:
var mapper = function () {
var x = parseInt(this.moop);
emit(this.PartnerID, x);
};
두 로 대응하는 축소 합니다.keyCustId
그리고.valuesMoop
.valuesMoop
정요니 배다열입수인 배열입니다.moop
되어 맵 함수에 의해 은 맵 함수에 의해 그룹화됩니다.keyPartnerID
은 이기은다감니다킵소시음을능▁the를 줄여줍니다.valuesMoop
요소의 합에 대한 배열.
var reducer = function(keyPartnerID, valuesMoop) {
return Array.sum(valuesMoop);
};
db.collection.mapReduce(
mapper,
reducer,
{
out : "example_results",
query: {
Date: {
$gt: "2015-04-01",
$lt: "2015-04-05"
}
}
}
);
db.example_results.find(function (err, docs) {
if(err) console.log(err);
console.log(JSON.stringify(docs));
});
예를 들어, 다음 문서의 샘플 컬렉션을 사용합니다.
/* 0 */
{
"_id" : ObjectId("550c00f81bcc15211016699b"),
"Date" : "2015-04-04",
"PartnerID" : "123456",
"moop" : "1234"
}
/* 1 */
{
"_id" : ObjectId("550c00f81bcc15211016699c"),
"Date" : "2015-04-03",
"PartnerID" : "123456",
"moop" : "24"
}
/* 2 */
{
"_id" : ObjectId("550c00f81bcc15211016699d"),
"Date" : "2015-04-02",
"PartnerID" : "123457",
"moop" : "21"
}
/* 3 */
{
"_id" : ObjectId("550c00f81bcc15211016699e"),
"Date" : "2015-04-02",
"PartnerID" : "123457",
"moop" : "8"
}
Map/를 "/Reduce"로 합니다.example_results
및 명령어는 다음과 같습니다.db.example_results.find()
다음을 제공:
/* 0 */
{
"_id" : "123456",
"value" : 1258
}
/* 1 */
{
"_id" : "123457",
"value" : 29
}
문자열 데이터 유형을 숫자 데이터 유형으로 쉽게 변환할 수 있습니다.
컬렉션 이름 및 필드 이름을 변경하는 것을 잊지 마십시오.for ex : CollectionNmae : Users & Field Name : Contact no.
이 쿼리를 사용해 보십시오.
db.collectionName.find().forEach( function (x) {
x.FieldName = parseInt(x.FieldName);
db.collectionName.save(x);
});
결국 나는 사용했습니다.
db.my_collection.find({moop: {$exists: true}}).forEach(function(obj) {
obj.moop = new NumberInt(obj.moop);
db.my_collection.save(obj);
});
방향을 틀다moop
MongoDB: 필드 유형을 변경하는 방법?의 예에 따라 my_collection의 문자열에서 정수로 변환합니다.
문자열은 $toInt 연산자를 사용하여 MongoDB v4.0에서 숫자로 변환할 수 있습니다.이 경우
db.col.aggregate([
{
$project: {
_id: 0,
moopNumber: { $toInt: "$moop" }
}
}
])
출력:
{ "moopNumber" : 1234 }
여기 제가 방금 재미로 작성한 이 문제에 대한 순수한 MongoDB 기반 솔루션이 있습니다.서버 측 문자열 대 숫자 파서로서 양수 및 음수와 소수를 지원합니다.
db.collection.aggregate({
$addFields: {
"moop": {
$reduce: {
"input": {
$map: { // split string into char array so we can loop over individual characters
"input": {
$range: [ 0, { $strLenCP: "$moop" } ] // using an array of all numbers from 0 to the length of the string
},
"in":{
$substrCP: [ "$moop", "$$this", 1 ] // return the nth character as the mapped value for the current index
}
}
},
"initialValue": { // initialize the parser with a 0 value
"n": 0, // the current number
"sign": 1, // used for positive/negative numbers
"div": null, // used for shifting on the right side of the decimal separator "."
"mult": 10 // used for shifting on the left side of the decimal separator "."
}, // start with a zero
"in": {
$let: {
"vars": {
"n": {
$switch: { // char-to-number mapping
branches: [
{ "case": { $eq: [ "$$this", "1" ] }, "then": 1 },
{ "case": { $eq: [ "$$this", "2" ] }, "then": 2 },
{ "case": { $eq: [ "$$this", "3" ] }, "then": 3 },
{ "case": { $eq: [ "$$this", "4" ] }, "then": 4 },
{ "case": { $eq: [ "$$this", "5" ] }, "then": 5 },
{ "case": { $eq: [ "$$this", "6" ] }, "then": 6 },
{ "case": { $eq: [ "$$this", "7" ] }, "then": 7 },
{ "case": { $eq: [ "$$this", "8" ] }, "then": 8 },
{ "case": { $eq: [ "$$this", "9" ] }, "then": 9 },
{ "case": { $eq: [ "$$this", "0" ] }, "then": 0 },
{ "case": { $and: [ { $eq: [ "$$this", "-" ] }, { $eq: [ "$$value.n", 0 ] } ] }, "then": "-" }, // we allow a minus sign at the start
{ "case": { $eq: [ "$$this", "." ] }, "then": "." }
],
default: null // marker to skip the current character
}
}
},
"in": {
$switch: {
"branches": [
{
"case": { $eq: [ "$$n", "-" ] },
"then": { // handle negative numbers
"sign": -1, // set sign to -1, the rest stays untouched
"n": "$$value.n",
"div": "$$value.div",
"mult": "$$value.mult",
},
},
{
"case": { $eq: [ "$$n", null ] }, // null is the "ignore this character" marker
"then": "$$value" // no change to current value
},
{
"case": { $eq: [ "$$n", "." ] },
"then": { // handle decimals
"n": "$$value.n",
"sign": "$$value.sign",
"div": 10, // from the decimal separator "." onwards, we start dividing new numbers by some divisor which starts at 10 initially
"mult": 1, // and we stop multiplying the current value by ten
},
},
],
"default": {
"n": {
$add: [
{ $multiply: [ "$$value.n", "$$value.mult" ] }, // multiply the already parsed number by 10 because we're moving one step to the right or by one once we're hitting the decimals section
{ $divide: [ "$$n", { $ifNull: [ "$$value.div", 1 ] } ] } // add the respective numerical value of what we look at currently, potentially divided by a divisor
]
},
"sign": "$$value.sign",
"div": { $multiply: [ "$$value.div" , 10 ] },
"mult": "$$value.mult"
}
}
}
}
}
}
}
}
}, {
$addFields: { // fix sign
"moop": { $multiply: [ "$moop.n", "$moop.sign" ] }
}
})
저는 이것을 '무릎팍도' 같은 것으로 광고하지 않을 것이며, 클라이언트 기반 솔루션보다 대규모 데이터셋에 심각한 성능 영향을 미칠 수도 있지만, 유용한 경우가 있을 수도 있습니다.
위의 파이프라인은 다음 문서를 변환합니다.
{ "moop": "12345" } --> { "moop": 12345 }
그리고.
{ "moop": "123.45" } --> { "moop": 123.45 }
그리고.
{ "moop": "-123.45" } --> { "moop": -123.45 }
그리고.
{ "moop": "2018-01-03" } --> { "moop": 20180103.0 }
다음 세 가지 사항을 주의해야 합니다.
- parseInt()는 mongodb에 이중 데이터 유형을 저장합니다.새 번호를 사용하십시오.Int(문자열).
- 대량 사용을 위한 Mongo 셸 명령에서 수율이 작동하지 않습니다.'수익률'을 추가하지 마십시오.
- 문자열을 parseInt()에 의해 이중으로 이미 변경한 경우.당신은 타입을 int로 직접 변경할 방법이 없는 것 같습니다.해결책은 약간 유선형입니다. 먼저 더블을 문자열로 변경한 다음 새로운 NumberInt()에 의해 다시 int로 변경합니다.
모든 문서를 통합하여 편집할 수 있는 경우:
"TimeStamp": {$toDecimal: {$toDate: "$Your Date"}}
클라이언트의 경우 쿼리를 설정합니다.
Date.parse("Your date".toISOString())
그것이 바로 당신이 아이소데이트와 함께 일하는 이유입니다.
시도:
"TimeStamp":{$toDecimal: { $toDate:"$Datum"}}
그래도$toInt
정말 유용합니다. mongoDB 4.0에 추가되었습니다. 3.2를 실행하는 데이터베이스에서 사용하기 위해 업그레이드한 것과 같은 상황에 부딪혔습니다.$toInt
다른 애플리케이션의 비호환성 때문에 옵션이 아니었기 때문에 다른 방법을 생각해내야 했고, 실제로는 놀라울 정도로 간단했습니다.
네가 만약$project
그리고.$add
당신의 끈에 0, 그것은 숫자로 변할 것입니다.
{
$project : {
'convertedField' : { $add : ["$stringField",0] },
//more fields here...
}
}
그것은 저장되어야 합니다.다음과 같이 해야 합니다.
db. my_collection.find({}).forEach(function(theCollection) {
theCollection.moop = parseInt(theCollection.moop);
db.my_collection.save(theCollection);
});
데이터 정렬이 필요합니다.
db.collectionName.find().sort({PartnerID: 1}).collation({locale: "en_US", numericOrdering: true})
db.user.find().toArray().filter(a=>a.age>40)
언급URL : https://stackoverflow.com/questions/29487351/how-to-convert-string-to-numerical-values-in-mongodb
'source' 카테고리의 다른 글
Node.js에서 단일 스레드 비차단 IO 모델이 작동하는 방식 (0) | 2023.05.24 |
---|---|
문자열에서 선행 쉼표 제거 (0) | 2023.05.24 |
창에서 Git Bash의 'git diff' 결과를 종료하려면 어떻게 해야 합니까? (0) | 2023.05.14 |
Enum 특성에 대한 주석 유형 (0) | 2023.05.14 |
Git fetch 또는 pull을 사용한 자동 자르기 (0) | 2023.05.14 |