2015-12-02 53 views
2

我有我的應用3種不同的模式:定義3種模式MongoDB中具有不同的關係(很多到多,一到多...)

userSchema, questionSchema, listingSchema 

三者之間的關係是如下:

每個列表有很多與它相關的問題(每個列表相同的問題)。
每個用戶可以回答在幾個列表中的許多問題。
每個問題許多用戶在許多列表中回答。

我試圖環繞確定這些模式之間的正確關係(主要是因爲像「與_id = 100用戶的列表回答的問題與_id = 5_id = 3,我該如何更新所有這些最有效的問題,我的頭路)

到目前爲止,我已經定義爲:?

questionSchema:

var questionSchema = new Schema({ 
    description: String 
}); 

userSchema:

var userSchema = new Schema({ 

    local   : { 
     email  : String, 
     password  : String, 
     name   : String 
    }, 
    ApartmentsAndQuestions: [{ 
     apartmentID: String, 
     questionID: [String] /* one apartment -> multiple questions */ 
    }] 
}); 

而且listingSchema:

var listingSchema = new Schema({ 
    street   : String, 
    buildingNumber : Number, 
    apartmentNumber : Number, 
    type   : String, 
    floor   : Number, 
    outOfFloors  : Number, 
    numberOfRooms : Number, 
    size   : Number, 
    renovated  : Boolean, 
    elevator  : Boolean, 
    airConditioning : Boolean, 
    balcony   : Boolean, 
    price   : Number, 
    description  : String, 
    flagCount  : Number, 
    pictures  : [imageSchema] 
    owner   : [userSchema] 

    UsersAndQuestions: [{ 
      userID: String, 
      questionID: [String] /* one user -> multiple questions asked possible */ 
    }] 
}); 

問題:我如何把它做好,我的NoSQL數據庫?我的定義是否有意義?有沒有更好的方式來描述這些模式之間的關係?

任何幫助將大大讚賞!

+0

你要問一個具體問題的一個問題。 「這是否有意義」不是一個真正的問題,而是要求驗證。 –

+0

我認爲這是一個有效的問題,要問我的設計是否有意義,或者如果有更好的東西,我不知道或沒有正確實施 – Idos

+0

你至少試過,如果它的工作?如果它在工作並且完成了你設計它所要做的事情 - 它會讓人感覺到。如果它不起作用,那麼爲什麼 - 是否有任何錯誤或者您有什麼問題?那些問題是什麼?我沒有看到任何這些信息。在提出問題之前請付出一些努力。 –

回答

0

您將要定義你的架構如下:

var userSchema = mongoose.Schema({ 

    local   : { 
     email  : String, 
      password  : String, 
      name    : String 
    }, 
    /* every entry in the array is an apartment ID and the questionsIDs (array) of the questions that the user ALREADY answered in that *specific* apartment */ 
    ApartmentsAndQuestions: [{ 
     apartmentID : String, 
     questionsIDs: [String] 
    }] 
}); 

和:

var listingSchema = new Schema({ 
    street   : String, 
    buildingNumber : Number, 
    apartmentNumber : Number, 
    type   : String, 
    floor   : Number, 
    outOfFloors  : Number, 
    numberOfRooms : Number, 
    size   : Number, 
    renovated  : Boolean, 
    elevator  : Boolean, 
    airConditioning : Boolean, 
    balcony   : Boolean, 
    price   : Number, 
    description  : String, 
    flagCount  : Number, 
    ownerID   : String, 
    /* every entry in the array is a userID and the questionsIDs (array) of the questions that the user ALREADY answered in that *specific* apartment */ 
    UsersAndQuestions: [{ 
     userID: String, 
     questionID: [String] 
    }], 
    /* every image has a count of how many times the users answered YES or NO on it */ 
    imagesAndCount: [{ 
     imageID: String, 
     count: Number 
    }] 
}); 

那麼你基本上可以做的東西線:

var someuser = db.users.find()[2] // get some user 

someuser._id >>>返回ObjectId("56472a83bd9fa764158d0cb6") 然後:db.users.find({_id: ObjectId("56472a83bd9fa764158d0cb6")}) >>> which will return someuser (with all the fields that are defined in the User schema)

然後:db.listings.insert({"street" : "SomeStreet", "buildingNumber" : 33, "apartmentNumber" : 63, "beds": 3, "owner" : "56472a83bd9fa764158d0cb6"})

而上市將是這樣的:
現在上市是這樣的:

{ 
    "_id": { 
     "$oid": "566c220abcda51a9eef08576" 
    }, 
    "street": "SomeStreet", 
    "buildingNumber": 33, 
    "apartmentNumber": 63, 
    "beds": 3, 
    "owner": "56472a83bd9fa764158d0cb6" 
} 
+0

看起來非常好!這個例子真的幫助我理解!非常感謝 :) – Idos

1

MongoDB的3.2+解決方案

加入評論mentionned,您可以使用新的$lookup避免嵌入大量的數據。這就像一個SQL LEFT JOIN:

讓我們添加一些數據,匹配你:

db.questionSchema.insert({ _id: 1, description: "My description 1" }); 
db.questionSchema.insert({ _id: 2, description: "My description 2" }); 
db.questionSchema.insert({ _id: 3, description: "My description 3" }); 
db.questionSchema.insert({ _id: 4, description: "My description 4" }); 

db.userSchema.insert({ _id: 1, email: "[email protected]", ApartmentsAndQuestions: [] }); 
db.userSchema.insert({ _id: 2, email: "[email protected]", ApartmentsAndQuestions: [] }); 

db.listingSchema.insert({ _id: "A", UsersAndQuestions: [] }) 
db.listingSchema.insert({ _id: "B", UsersAndQuestions: [] }) 

// Add some questions 
db.userSchema.update({ _id: 1 }, { $addToSet: { ApartmentsAndQuestions: { apartment_id: 1, question_id: [1] } } }) 
db.userSchema.update({ _id: 1, "ApartmentsAndQuestions.apartment_id": 1 }, { $addToSet: { "ApartmentsAndQuestions.$.question_id": 3 } }) 

db.userSchema.update({ _id: 2 }, { $addToSet: { ApartmentsAndQuestions: { apartment_id: 2, question_id: [1,2] } } }) 
db.userSchema.update({ _id: 2, "ApartmentsAndQuestions.apartment_id": 2 }, { $addToSet: { "ApartmentsAndQuestions.$.question_id": 4 } }) 

db.listingSchema.update({ _id: "A" }, { $addToSet: { UsersAndQuestions: { user_id: 1, question_id: [1] } } }) 

與常規的發現,這裏是你會得到什麼:

test> db.listingSchema.find() 
{ 
    "_id": "B", 
    "UsersAndQuestions": [ ] 
} 
{ 
    "_id": "A", 
    "UsersAndQuestions": [ 
    { 
     "user_id": 1, 
     "question_id": [ 
     1 
     ] 
    } 
    ] 
} 

然後,讓我們$查找:

db.listingSchema.aggregate([ 
    { 
     $unwind: "$UsersAndQuestions" 
    } 
    ,{ 
     $lookup: 
     { 
      from: "userSchema", 
      localField: "UsersAndQuestions.user_id", 
      foreignField: "_id", 
      as: "fetched_user" 
     } 
    } 
    ,{ 
     $unwind: "$UsersAndQuestions.question_id" 
    } 
    ,{ 
     $lookup: 
     { 
      from: "questionSchema", 
      localField: "UsersAndQuestions.question_id", 
      foreignField: "_id", 
      as: "fetched_question" 
     } 
    } 
]) 

你得到:

{ 
    "waitedMS": NumberLong("0"), 
    "result": [ 
    { 
     "_id": "A", 
     "UsersAndQuestions": { 
     "user_id": 1, 
     "question_id": 1 
     }, 
     "fetched_user": [ 
     { 
      "_id": 1, 
      "email": "[email protected]", 
      "ApartmentsAndQuestions": [ 
      { 
       "apartment_id": 1, 
       "question_id": [ 
       1, 
       3 
       ] 
      } 
      ] 
     } 
     ], 
     "fetched_question": [ 
     { 
      "_id": 1, 
      "description": "My description 1" 
     } 
     ] 
    } 
    ], 
    "ok": 1 
} 

然後,您也可以$ ApartmentsAndQuestions.questions_id也解開$查找問題數據。隨你便。

+0

嘿,我真的很感謝這個努力,但我甚至都沒有問過這些。我知道如何使用find()或其他數據庫函數...我問了關於Schema關係和最好的方法來根據我的需要定義每個... Upvoted any way – Idos