oznomal
oznomal

Reputation: 449

One to many mapping with Mongo DB

I am new to mongodb and am looking to design something that would be fairly straight forward with a RDBMS.

I have an existing document of Musical Artists and each artist has a collection of 'Artist Aliases' (String). My goal is to ensure that an artist is only really in my DB one time, but since many artists have multiple spellings and names I have created the aliases collection so I will be able to know that these other spellings and names are actually linked to this 1 particular artist in my DB. With a traditional relational database I could easily accomplish this by having a join table for the aliases and then using a FK to point to the corresponding artist. However I am not sure how to approach this in MongoDB with Spring-Data.

I am unsure if I need to create an Artist object as well as an ArtistAlias object, or if there is just a way that I can embed the ArtistAlias info inside of the artist object and search it from there. I know that I can embed the information, but I am not sure how to query it .... Like for instance if I had an artist named 'Michael Jackson' stored in my DB but he had an alias of 'MJ' and I just wanted to search for that, but pull back the full 'Micahel Jackson' artist info, can I achieve that without having to create a separate document to hold all of the ArtistAlias objects?

Currently:

@Document(collection = "artist")
public class Artist
{
    @Id
    private String id;

    @TextIndexed
    private String artistName;

    @TextScore
    private Float textScore;

    private Set<String> artistAliasSet;
}

What I know I could do

@Document(collection = "artist")
public class Artist
{
    @Id
    private String id;

    @TextIndexed
    private String artistName;

    @TextScore
    private Float textScore;

    private Set<ArtistAlias> artistAliasSet;
}
@Document(collection = "artist_alias")
public class Artist
{
    @Id
    private String id;

    @TextIndexed
    private String aliasName;

    @TextScore
    private Float textScore;

    private Artist artist;
}

However, this approach really concerns me because new artist are constantly getting added to the DB and since the ID of either a new artist or alias won't be assigned until after the save, this means when new artists are added I'll have to make 3 calls to the DB for each one. First, I'd need to save the alias with the Artist field null in order to get the aliases id back, then I'd need to save the artist with the newly learned alias info to get the ID for the artist, and lastly I'd need to go back and update the alias with with the new artist ID and info I got back after the save. I feel like there has to be a better approach then this.

Upvotes: 0

Views: 372

Answers (2)

marcopiii
marcopiii

Reputation: 888

If the aliases are supposed to be referenced only by the artist objects there is no need to create a separate collection, you can just embed them as an alias array in the Artist. Here you can find some considerations about when to ember and when to reference.

If you have an artists collection with objects like

{
    "name": "Michael Jackson",
    "alias": [
        "mj",
        "king of the pop"
    ]
}

You can use

db.artists.find({"alias": "mj"})

to query for all documents where alias is an array that contains the string "mj" as one of its elements.

Also check official documentation about query array.

Upvotes: 1

Dina Bogdan
Dina Bogdan

Reputation: 4698

One-To-Many relationship from Relational world doesn't exist in the NoSQL world. You can emulate something similar in the way that you can store a collection of documents under another document (a relationship like parent-childs). You can find more here

Upvotes: 1

Related Questions