2014-09-03 3 views
0

정상적인 숫자 (32 비트)와 큰 숫자 (64 비트) 인 을 포함하는 배열을 가진 mongodb 문서를 가지고 있고이 문서를 노드 javascript 드라이버 mongodb 용.자바 스크립트로 MongoDB에서 64 비트 숫자 쿼리하기

mongo 셸에서 문서를 쿼리 할 때 NumberLong으로 인쇄 된 64 비트 숫자를 볼 수 있습니다. 예를 들어 :

NumberLong("1099511627776")은 기본적으로 두 가지 질문 :

(1) 값이 64 비트 수 있는지 확인하기 위해 깨끗한 방법이 있나요? 오늘은 (2) 어떻게 mongo.Long의 인스턴스로이 값을 캐스팅 할

if (typeof counters[slot] !== "number") { 
    // I assume counters[slot] is a 64-bit object 
} 

제거하는 것입니다 다음 식을 사용합니까? 오늘 나는 몽고에 던지다. 길고 길다. 캐스트를 수행하는 더 깨끗한 방법이 있습니까?

var mongoLong = require('mongodb').Long; 
if (typeof counters[slot] !== "number") { 
    var bigNumber = mongoLong(counters[slot].low_, counters[slot].high_); 
    // do things with bigNumber 
} 

고마워요!

참고 : Long을 Long으로 캐스트해야하는 이유가 궁금 할 수 있습니다. MongoDB 자바 스크립트 드라이버 쿼리에서 이 반환 한 "Long"값이 이 아니기 때문에 이유는 Long 클래스의 인스턴스가 아니기 때문입니다. 즉 Long() 생성자로 생성되지 않았습니다. 즉, getHighBits() 또는 isNegative()처럼 멤버 함수를 호출 할 수 없습니다.

답변

0

오케이. MongoDB에서 다른 BSON 유형으로 저장된 숫자를 얻을 수있는 몇 가지 방법이 있습니다. 우선의 첫 번째 셸에서이 정보를 살펴 보자 :

:

db.numbers.insert({ "n": NumberLong(1) })  // 64bit 
db.numbers.insert({ "n": NumberInt(1) })  // 32bit 
db.numbers.insert({ "n": 1 })     // Actually a Double! 

모든 차이 BSON의 그림과 같이 유형, 각각의 쿼리하는 가장 좋은 방법은 해당 필드 "유형"에 대한 테스트하는 $type 연산자를 사용하고 있습니다

db.numbers.find(function() { return typeof(this.n) == "number" }) 
db.numbers.find(function() { return typeof(this.n) == "object" }) 
: 당신이 당신의 현재 테스트로, 자바 스크립트 평가를 한 후 마지막 두 응답을 이렇게했는데, 그것은 "대해서 typeof"다만 반환 개체입니다 64 비트 결과가 아니라면
db.numbers.find({ "n": { "$type": 18 } })  // 64bit 
db.numbers.find({ "n": { "$type": 16 } })  // 32bit 
db.numbers.find({ "n": { "$type": 1 } })  // Double 

마지막 테스트 만 64Bit 정수와 일치하기 때문에 JavaScript에서이 테스트 방법이 사용됩니다. 하지만 실제로 위의 $type 테스트는 쿼리에서 직접 사용할 수 있고 원시 코드를 사용할 수 있으므로 더 좋습니다. 네이티브 코드는 쿼리 내부 또는 외부의 JavaScript 평가보다 좋기 때문에이를 사용하는 것이 가장 좋습니다. 그리고 더 빠릅니다.

변환 할 전체 묶음이 있으면 컬렉션을 반복하고 Long으로 변환하고 다시 작성해야합니다. 그리고 Long.fromInt를 사용하여뿐만 아니라, 물론 같은 대량 쓰기 작업과 루프 처리하고 구성하는 가장 좋은 방법 :

var async = require('async'), 
    MongoClient = require('mongodb').MongoClient, 
    Long = require('mongodb').Long; 


MongoClient.connect('mongodb://localhost/test',function(err,db) { 

    db.collection('numbers',function(err,collection) { 

    var bulk = collection.initializeOrderedBulkOp(); 
    var count = 0; 

    var stream = collection.find(
     { 
     "$or": [ 
      { "n": { "$type": 16 } }, 
      { "n": { "$type": 1 } } 
     ] 
     } 
    ).stream(); 

    stream.on('data',function(data) { 
     bulk.find({ "_id": data._id }).updateOne({ 
     "$set": { "n": Long.fromInt(data.n) } 
     }); 

     if (count % 1000 == 0) { 
     stream.pause(); 
     bulk.execute(function(err,result) { 
      if (err) throw err; 
      bulk = collection.initializeOrderedBulkOp(); 
      stream.resume(); 
     }); 
     } 

    }); 

    stream.on('end',function() { 
     if (count % 1000 != 0) 
     bulk.execute(function(err,result) { 
      if (err) throw err; 
      bulk = collection.initializeOrderedBulkOp(); 
     }); 
     console.log("done"); 
     process.exit(); 
    }); 

    }); 

}); 

단지 예를 작동하는 기본 전제, 그러나 그것은 전체 수집과 비밀을 통과하는 가장 좋은 방법 원하는 유형.

+0

좋은 생각인데, 그렇게 할 수 있습니다. 하지만 실제로 내 질문에 대답하지 않습니다. 쿼리 변경에 관심이 없습니다. 각 문서에는 여러 값이 있습니다. 그래서 나는 문서 안의 값들을 반복하고 각 값의 타입을 결정할 필요가있다. 또한 질문 (2)이 있습니다. –

+0

@GaryWeiss 그럼 두 가지 질문은 캐스팅하는 방법 이었으므로 보여지는 Long.fromInt를 사용합니다. 어떤 필드에 변환하려는 값이 포함되어 있는지 확실하지 않은 경우 쿼리를 생략하고 요소를 검사하여 조건과 일치하는지 확인하십시오. 그게 당신이 (1)에 도움이 필요한 문제입니까? –

+0

질문 1에 대해 Long.isLong (x)라는 함수가 필요할 것으로 생각합니다. 두 번째 질문의 경우, 반환 된 값은 ({_bsontype : 'Long', low_ : -1342987186, high_ : 147890796})과 같은 객체이지만 Long 함수를 호출 할 수 없기 때문에 실제로는 Long이 아닙니다. 과()). 그러면 나는 어떻게 그것을 선의의 Long에 던지나요? fromInt를 사용하면 (뭔가 놓친 경우를 제외하고는) 작동하지 않습니다. 나는 내가 Long.fromObj (x)를 찾고 있다고 생각한다. –

관련 문제