Is it possible to assign Objectid() to subcollections in Mongodb?

Asked

Viewed 1,215 times

0

Imagine the following Gospel:

{
    _id:ObjectId("123456..."),
    user:"João",
    artigos:[
        {
            id: new ObjectId(),
            titulo:"Lorem ispsum.",
            texto:"Lorem ipsum dolor sit amet..."
        }
    ]
}

In short: A user may have n articles, which in turn need some form of identification to be found in a consultation.

Only apparently Mongodb won’t accept ObjectId() in subcollections, I tried to generate this way and it triggers an error stating that it was not possible to do the parse of the JSON file. So my question is:

It is possible to add ObjectId() in subcollections? If not, how could I assign ids to my items within this subcollection?

2 answers

1

It is possible to add ObjectId() in subcollections (or rather subdocuments)?

Yes, but this is not very recommended, because considering that the data architecture decision was to put the data as a subdocument, it is assumed that the only important key is the parent document.

Of course there are exceptions. If for example we are talking about a person who has n addresses, and we just want to update one of them, and this is a recurring operation. It makes sense to have.

I’m guessing to the example that Schema’s statement goes something like this:

Pessoa: {
    enderecos: [
        { _id: ObjectId(), nome: '' },
        ...
    ]
}

I did a test with your example and it worked as follows:

db.pessoas.insert({
    "_id": ObjectId(),
    "user": "João",
    "artigos": [
        {
            "_id": ObjectId(),
            "titulo": "Lorem ispsum.",
            "texto": "Lorem ipsum dolor sit amet..."
        }
    ]
})
  • But that’s it, I do it, but when I try to add to the bank he accuses error, saying that he expected a string or data.

  • I think this is wrong: id: new ObjectId(). Would not be _id: ObjectId()?

  • I’ve tried without the new and also accuses error. In case I already own a ObjectId() out of that subdocument (as it appears there in the JSON of my question), is that only one is allowed by Document and so triggers error?

  • I don’t think so. It might just be a syntactic problem. I’m going to take a test here.

  • @Kazzkiq I edited my answer and put your test. Here it worked perfectly in the pure shell of Mongodb.

0

This is a matter of document design. Roughly, there are two routes to follow:

  1. include the subdocument (artigo) within the root document (usuario)
  2. link/reference the secondary document (artigo) in primary school (usuario)

Since you seem to need an identifier for each article, I would suggest first trying to find a natural identifier, like an existing unique archive number. If this is not possible, you can generate any unique identifier at the time of saving the article for the first time, like a UUID/GUID or some string derived from the title and possibly publication date (e.g.: id_artigo: "2014_08_03_lorem_imsum").

If you prefer a sequential number for these articles, one simple way to achieve this is by creating an auxiliary Collection sequencias that you can use to generate these numbers. I use this technique quite a lot with findAndModify():

var contador = db.sequencias.findAndModify({
    query: {'_id': 'artigos'},
    fields: {'_id': 0, 'seq': 1},
    update: {'$inc': {'seq': 1}},
    new: true,
    upsert: true
});
var novo_num = contador.seq;

The alternative 1 applies well when articles have only one author/user, as you will not duplicate anything:

{
    _id: ObjectId("123456..."),
    user: "João",
    artigos:[
        {
            id_artigo: "2014_08_03_lorem_impsum",
            data: new Date(2014, 07, 03), 
            titulo: "Lorem ispsum.",
            texto: "Lorem ipsum dolor sit amet..."
        },
        {
            id_artigo: "2013_12_01_so_um_teste",
            data: new Date(2013, 11, 01), 
            titulo: "Só um Teste",
            texto: "Meu primeiro artigo..."
        }

    ]
}

Already the alternative 2 can be used when there is the possibility of the same article being related to more than one author/user, avoiding much duplication of data:

Articles:

    {
        _id: "2014_08_03_lorem_impsum",
        data: new Date(2014, 07, 03), 
        titulo: "Lorem ispsum.",
        texto: "Lorem ipsum dolor sit amet..."
    }

    {
        _id: "2013_12_01_so_um_teste",
        data: new Date(2013, 11, 01), 
        titulo: "Só um Teste",
        texto: "Meu primeiro artigo..."
    }

Users:

{
    _id: ObjectId("123456..."),
    user: "João",
    artigos: ["2013_12_01_so_um_teste", "2014_08_03_lorem_impsum"]
}

{
    _id: ObjectId("987654..."),
    user: "Armando",
    artigos: ["2014_08_03_lorem_impsum"]
} 

Browser other questions tagged

You are not signed in. Login or sign up in order to post.