Home > Software engineering >  Is there a way to insert in only one document the nested review associated even if some attributes o
Is there a way to insert in only one document the nested review associated even if some attributes o

Time:01-15

Hi everybody I'm trying to build a Social Network with wines. For my application I'm using MongoDB and Neo4J. On my Document DB I'm storing Wines and for each wines i'm storing inside like nested document all the rewiews associated.

Wine has these attributes

instead

Wine_Reviews has these attributes

If I don't change Wines' value MongoDB create one document and all reviews associated are inserted like nested document (RIGHT) for that wine but if I change one attribute of the wine like "Province", MongoDB will create two document so two wines even if the title is the same. Wrong situation

My question is: Is it possibile to avoid this situation? Insert in one document all wines with same title even if ALL other attributes of the same wine change? (Works correctly only if attributes are the same)

Correct situation but here wine attrbiutes don't change for reviews inserted

This is the code of Crud_mongo.java:

   public void createWine(String title, String variety, String country, String province, int price, String taster_name, Integer points,
                       String description, String taster_twitter_handle, String country_user, String e_address, Boolean admin) {
    final MongoClient mongoClient = new MongoClient(new MongoClientURI("mongodb://localhost:27017"));
    MongoDatabase database = mongoClient.getDatabase("Wines");
    MongoCollection<Document> collection = database.getCollection("wines");

    Document wine = new Document("title", ""   title   "")
            .append("title", ""   title   "")
            .append("variety", ""   variety   "")
            .append("country", ""   country   "")
            .append("province", ""   province   "")
            .append("price", ""   price   "");

    Document user = new Document("taster_name", ""   taster_name   "")
            .append("score", ""   points   "")
            .append("description", ""   description   "")
            .append("taster_twitter_handle", ""   taster_twitter_handle   "")
            .append("country", ""   country_user   "")
            .append("email", ""   e_address   "")
            .append("admin", ""   admin   "");

    MongoCursor<String> cursormedia = collection.distinct(title, String.class).iterator();
    MongoCursor<String> cursor = collection.distinct("_id.title", String.class).iterator();
    UpdateOptions options = new UpdateOptions().upsert(true);

    Bson filter = Filters.eq(wine);
    Bson setUpdate = Updates.push("wine_reviews", user);
    collection.updateMany(filter, setUpdate, options);
    System.out.println("Successfully inserted review. \n");

    }


    

CodePudding user response:

The current (wrong) behavior is consistent with your setup of _id. _id must be unique and besides title you have 4 other fields that compose this complex key including province so if you change any of the other 4, a new document is created.

It is always good to separate DB internal keys (like _id) from business/data domain keys (like title and some of the other attributes). I recommend you let the MongoDB driver take care of constructing _id upon insert and moving the other fields out into the document proper, e.g.

{
    _id: ObjectId('61e190fc3105a836ad0dc8b1'),
    title: "VINO",
    variety: "Rosato",
    country: "Germania",
    province: "a",
    price: 50,
    reviews: [
        {taster_name: "Prova1", score: 50 ...

You can now update with ease:

db.collection.update({_id:ObjectId('61e190fc3105a836ad0dc8b1')},{$set: {province:"b"}});

_id is unique so it will only update one document. If you choose to update using other criteria it may or may not update multiple documents but you can control that. For example, assume title variety country is not unique and you want all such wines to be in province "b", then use the multi option as follows:

db.collection.update({title:'VINO',variety:'Rosato',country:'Germania')},
{$set: {province:"b"}},
{multi:true});
  •  Tags:  
  • Related