ti-enxame.com

Incremento automático no MongoDB para armazenar a sequência de ID do usuário exclusivo

Estou fazendo um sistema de análise, a chamada da API forneceria uma ID de usuário exclusiva, mas não está em seqüência e é muito escassa.

Eu preciso dar a cada ID de usuário exclusivo um ID de incremento automático para marcar um ponto de dados de análise em uma bitarray/bitset. Assim, o primeiro usuário encontra correspondendo ao primeiro bit da bitarray, o segundo usuário seria o segundo bit na bitarray, etc.

Então, há uma maneira sólida e rápida de gerar IDs de usuário exclusivos incrementais no MongoDB?

17
est

Você pode, mas você não deve https://web.archive.org/web/20151009224806/http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing- campo/

Cada objeto no mongo já possui um id, e eles são ordenáveis ​​em ordem de inserção. O que há de errado em obter a coleta de objetos do usuário, iterá-la e usá-la como ID incrementada? Ir para um tipo de trabalho de redução de mapa

11
Konstantin Pribluda

Como a resposta selecionada diz que você pode usar o findAndModify para gerar IDs sequenciais.

Mas eu discordo fortemente da opinião de que você não deveria fazer isso. Tudo depende das necessidades do seu negócio. Ter um ID de 12 bytes pode consumir muitos recursos e causar problemas significativos de escalabilidade no futuro.

Eu tenho resposta detalhada aqui .

16
expert

Primeiro crie um counters collection, que irá acompanhar o último valor de seqüência para todos os campos da sequência.

        db.createCollection("counters")

Use o seguinte código para inserir este documento de sequência na coleção de contadores -

    db.counters.insert({_id:"tid",sequence_value:0})

Criando Função Javascript:

    function getNextSequenceValue(sequenceName){
        var sequenceDocument = db.counters.findAndModify({
        query:{_id: sequenceName },
        update: {$inc:{sequence_value:1}},
        new:true
          });
      return sequenceDocument.sequence_value;
      }

Inserir dois documentos:

            db.products.insert({
           "_id":getNextSequenceValue("tid"),
           "product":"Samsung",
           "category":"mobiles"
             })


           db.products.insert({
            "_id":getNextSequenceValue("tid"),
            "product":"Samsung S3",
            "category":"mobiles"
              })

Obter documentos inseridos:

            db.prodcuts.find()

SAÍDA

{"_id": 1, "produto": "Samsung", "categoria": "celulares"}

{"_id": 2, "produto": "Samsung S3", "categoria": "celulares"}

13
Rizwan Siddiquee

Eu sei que esta é uma pergunta antiga, mas vou postar minha resposta para a posteridade ... 

Depende do sistema que você está construindo e das regras de negócios específicas em vigor.

Eu estou construindo um CRM de moderada a grande escala em MongoDb, C # (Backend API) e Angular (Frontend web app) e encontrei ObjectId totalmente terrível para uso em Angular Roteamento para selecionar particular entidades. O mesmo com o roteamento do Controlador de API.

A sugestão acima funcionou perfeitamente para o meu projeto.

db.contacts.insert({
 "id":db.contacts.find().Count()+1,
 "name":"John Doe",
 "emails":[
    "[email protected]",
    "[email protected]"
 ],
 "phone":"555111322",
 "status":"Active"
});

A razão é perfeita para o meu caso, mas nem todos os casos é que, como o comentário acima afirma, se você excluir 3 registros da coleção, você terá colisões. 

Minhas regras de negócios afirmam que, devido aos nossos SLAs internos, não podemos excluir dados de correspondência ou registros de clientes por mais tempo do que o tempo de vida potencial do aplicativo que estou escrevendo e, portanto, marquei registros com um enum "Status" que é "ativo" ou "excluído". Você pode excluir algo da interface do usuário e informar "O contato foi excluído", mas tudo que o aplicativo fez foi alterar o status do contato para "Excluído" e, quando o aplicativo chamar o repositório de uma lista de contatos, eu filtrarei excluir registros excluídos antes de enviar os dados para o aplicativo cliente. 

Portanto, db.collection.find (). Count () + 1 é uma solução perfeita para mim ... 

Não funcionará para todos, mas se você não estiver excluindo dados, funciona bem.

7
Alex Nicholas

Primeiro registro deve ser adicionar 

"_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;

    }
 }
0
Darshan Vithani