programing

고유 사용자 ID의 시퀀스를 저장하기 위한 MongoDB의 자동 증분

magicmemo 2023. 5. 6. 14:30
반응형

고유 사용자 ID의 시퀀스를 저장하기 위한 MongoDB의 자동 증분

분석 시스템을 만들고 있는데 API 호출이 고유 사용자 ID를 제공하지만 순서가 맞지 않고 너무 희박합니다.

각 고유 사용자 ID에 자동 증분 ID를 지정하여 비트 배열/비트 집합에 분석 데이터 포인트를 표시해야 합니다.따라서 첫 번째 사용자는 비트 배열의 첫 번째 비트에 해당하고 두 번째 사용자는 비트 배열의 두 번째 비트에 해당합니다.

그렇다면 MongoDB에서 증분 고유 사용자 ID를 생성하는 견고하고 빠른 방법이 있습니까?

선택한 답변에 따르면 findAndModify를 사용하여 순차적인 ID를 생성할 수 있습니다.

하지만 저는 당신이 그렇게 해서는 안 된다는 의견에 강하게 반대합니다.모든 것은 비즈니스 요구사항에 따라 다릅니다.12바이트 ID를 사용하면 리소스가 매우 많이 소모되고 향후 상당한 확장성 문제가 발생할 수 있습니다.

여기에 자세한 답변이 있습니다.

수는 있지만, https://web.archive.org/web/20151009224806/http ://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/ 은 안 됩니다.

mongo의 각 개체는 이미 id를 가지고 있으며 삽입 순서로 정렬할 수 있습니다.사용자 개체의 컬렉션을 가져오고, 이를 반복하여 증분 ID로 사용하는 것은 무엇이 문제입니까?지도 같은 것을 찾아서 일을 완전히 축소합니다.

이것이 오래된 질문이라는 것을 알지만, 저는 후세를 위해 제 답을 게시할 것입니다.

구축하는 시스템과 특정 비즈니스 규칙에 따라 달라집니다.

MongoDb, C#(백엔드 API), Angular(프런트엔드 웹 앱)에서 중간 규모에서 대규모 CRM을 구축하고 있는데, ObjectId가 특정 엔티티를 선택하기 위한 Angular Routing에서 사용하기에는 완전히 형편없다는 것을 알게 되었습니다.API 컨트롤러 라우팅과 동일합니다.

위의 제안은 제 프로젝트에 완벽하게 들어맞았습니다.

db.contacts.insert({
 "id":db.contacts.find().Count()+1,
 "name":"John Doe",
 "emails":[
    "john@doe.com",
    "john.doe@business.com"
 ],
 "phone":"555111322",
 "status":"Active"
});

제 경우에 딱 맞는 이유는 위의 댓글처럼 컬렉션에서 3개의 레코드를 삭제하면 충돌이 발생하기 때문입니다.

제 비즈니스 규칙에 따르면 사내 SLA로 인해 현재 작성 중인 애플리케이션의 잠재적 수명보다 긴 기간 동안 대응 데이터 또는 클라이언트 레코드를 삭제할 수 없으며, 따라서 저는 단순히 "상태"라는 열거형("활성" 또는 "삭제됨")으로 레코드를 표시합니다.UI에서 무언가를 삭제할 수 있으며 "연락처가 삭제되었습니다"라고 표시되지만 응용 프로그램이 수행한 모든 작업은 연락처의 상태를 "삭제됨"으로 변경하는 것이며, 앱이 연락처 목록을 위해 리포지토리를 호출할 때 삭제된 기록을 필터링한 후 클라이언트 앱에 데이터를 푸시합니다.

따라서 db.collection.find().count() + 1은 저에게 완벽한 솔루션입니다.

모든 사용자에게 적합하지는 않지만 데이터를 삭제하지 않을 경우에는 정상적으로 작동합니다.

편집

피몽고의 최신 버전:

db.contacts.count() + 1

첫 번째 레코드를 추가해야 합니다.

"_id" = 1    in your db

$database = "demo";
$collections ="democollaction";
echo getnextid($database,$collections);

function getnextid($database,$collections){

     $m = new MongoClient();
    $db = $m->selectDB($database);
    $cursor = $collection->find()->sort(array("_id" => -1))->limit(1);
    $array = iterator_to_array($cursor);

    foreach($array as $value){



        return $value["_id"] + 1;

    }
 }

저도 비슷한 문제가 있었습니다. 즉, 식별자로 사용할 수 있지만 그럴 필요는 없는 고유 번호를 생성하는 것에 관심이 있었습니다.저는 다음과 같은 해결책을 생각해냈습니다.먼저 수집을 초기화합니다.

fun create(mongo: MongoTemplate) {
        mongo.db.getCollection("sequence")
                .insertOne(Document(mapOf("_id" to "globalCounter", "sequenceValue" to 0L)))
    }

그런 다음 고유한(및 오름차순) 숫자를 반환하는 서비스:

@Service
class IdCounter(val mongoTemplate: MongoTemplate) {

    companion object {
        const val collection = "sequence"
    }

    private val idField = "_id"
    private val idValue = "globalCounter"
    private val sequence = "sequenceValue"

    fun nextValue(): Long {
        val filter = Document(mapOf(idField to idValue))
        val update = Document("\$inc", Document(mapOf(sequence to 1)))
        val updated: Document = mongoTemplate.db.getCollection(collection).findOneAndUpdate(filter, update)!!
        return updated[sequence] as Long
    }
}

저는 id가 다른 솔루션들이 겪을 수 있는 동시 환경과 관련된 약점을 가지고 있지 않다고 생각합니다.

// await collection.insertOne({ autoIncrementId: 1 });
const { value: { autoIncrementId } } = await collection.findOneAndUpdate(
  { autoIncrementId: { $exists: true } },
  {
    $inc: { autoIncrementId: 1 },
  },
);
return collection.insertOne({ id: autoIncrementId, ...data });

에서 중첩된 쿼리와 같은 것을 사용했습니다.MySQL자동 증가를 시뮬레이션하는 것이 나에게 효과가 있었습니다. 최신정얻을 확인하려면 과 같이 .id1을 추가하면 다음과 같은 기능을 사용할 수 있습니다.

lastContact = db.contacts.find().sort({$natural:-1}).limit(1)[0];
db.contacts.insert({
    "id":lastContact ?lastContact ["id"] + 1 : 1, 
    "name":"John Doe",
    "emails": ["john@doe.com", "john.doe@business.com"], 
    "phone":"555111322",
    "status":"Active"
})

그것은 알렉스의 대답의 제거 문제를 해결합니다.중복되지 않음id레코드가 제거되면 나타납니다.

추가 설명:나는 그냥 이해합니다.id에 삽입한, " 가최근삽문입하서추다음나가한를다, ,▁the▁it다"로 합니다.id신기록의그리고 3차는 아직 기록이 없거나 모든 기록이 삭제된 경우를 대상으로 합니다.

이것은 또 다른 접근법이 될 수 있습니다.

const mongoose = require("mongoose");

const contractSchema = mongoose.Schema(
  {
    account: {
      type: mongoose.Schema.Types.ObjectId,
      required: true,
    },
    idContract: {
      type: Number,
      default: 0,
    },
  },
  { timestamps: true }
);

contractSchema.pre("save", function (next) {
  var docs = this;
  mongoose
    .model("contract", contractSchema)
    .countDocuments({ account: docs.account }, function (error, counter) {
      if (error) return next(error);
      docs.idContract = counter + 1;
      next();
    });
});

module.exports = mongoose.model("contract", contractSchema);
// First check the table length

const data = await table.find()
if(data.length === 0){
   const id = 1
   // then post your query along with your id  
}
else{
   // find last item and then its id
   const length = data.length
   const lastItem = data[length-1]
   const lastItemId = lastItem.id // or { id } = lastItem
   const id = lastItemId + 1
   // now apply new id to your new item
   // even if you delete any item from middle also this work
}

언급URL : https://stackoverflow.com/questions/8384029/auto-increment-in-mongodb-to-store-sequence-of-unique-user-id

반응형