Best way to structure my mongoose schema: inline array, padding, subdocument?

Here is my current outline

Brand Name:

var mongoose = require('mongoose'); var Schema = mongoose.Schema; var BrandSchema = new mongoose.Schema({ name: { type: String, lowercase: true , unique: true, required: true }, photo: { type: String , trim: true}, email: { type: String , lowercase: true}, year: { type: Number}, timestamp: { type : Date, default: Date.now }, description: { type: String}, location: { }, social: { website: {type: String}, facebook: {type: String }, twitter: {type: String }, instagram: {type: String } } }); 

Style:

 var mongoose = require('mongoose'); var Schema = mongoose.Schema; var StyleSchema = new mongoose.Schema({ name: { type: String, lowercase: true , required: true}, }); 

Product

 var mongoose = require('mongoose'); var Schema = mongoose.Schema; var ProductSchema = new mongoose.Schema({ name: { type: String, lowercase: true , required: true}, brandId : {type: mongoose.Schema.ObjectId, ref: 'Brand'}, styleId: {type: mongoose.Schema.ObjectId, ref: 'Style'}, year: { type: Number }, avgRating: {type: Number} }); 

Message:

 var mongoose = require('mongoose'); var Schema = mongoose.Schema; var PostSchema = new mongoose.Schema({ rating: { type: Number}, upVote: {type: Number}, brandId : {type: mongoose.Schema.ObjectId, ref: 'Brand'}, comment: {type: String}, productId: {type: mongoose.Schema.ObjectId, ref: 'Style'}, styleId: {type: mongoose.Schema.ObjectId, ref: 'Style'}, photo: {type: String} }); 

I am currently using the mongoose fill function:

 exports.productsByBrand = function(req, res){ Product.find({product: req.params.id}).populate('style').exec(function(err, products){ res.send({products:products}); }); }; 

This works, however, as a noob --- I started reading about performance issues with filling up the mongoose, as this is just adding an extra request.

For my post, especially, it seems that you can be taxed. The goal of this post should be a live twitter / instagram-like feed. It looks like there could be a lot of requests, which could slow down my application a lot.

Also, I want at some point I can search for prodcuts / post / brand by fields.

Should I consider embedding / embedding of this data (products embedded / embedded in brands)?

What is the most efficient circuit design or my setup will be fine - considering what I specified, I want to use it?


User History:

There will be an admin user.

The administrator will be able to add a Brand with certain fields in the Brand Scheme.

Brands will have related products, each product will have a style / category.


Search:

Users will be able to search for brands by name and location (I look at this with angular filtering / tags).

Users will be able to search for products by fields (name, style, etc.).

Users will be able to search by product brand and style.


Message:

Users will be able to post to the feed. When creating the Mail, they will select the Brand and Product to link the Mail to. The column will display the brand name, product name and style - along with the entered Post fields (photo, comment and rating).

Other users can click on the brand name to go to the brand’s display page. They can click on the product name to link to the product display page.

Product Page:

Show product fields from the above schema - including the associated style name from the style schema. It will also display a message related to a specific product.

Show brand page:

It will simply display the Brand fields and related products.


My main concern is the message that should fill out / request the brand, product and style in the feed.

Again, I’m thinking about whether to introduce products into the brand - then I can connect the product and brand style with Post for subsequent requests? Or maybe $ lookup or other aggregate functions.

+7
mongodb mongoose nosql
source share
1 answer

Mongodb itself does not support unions. Thus, the Mongoose Populate is an attempt at an external permission task. The thing with mongodb is that you need to construct your data in order to:

  • In most queries, you do not need to reference multiple collections.
  • after receiving the data from the request, you do not need to translate it too much.

Consider the entities involved and their relationships:

  • A brand is a brand. It does not depend on anything else.
  • Each product belongs to a brand.
  • Each product is associated with style.
  • Each message is associated with a Product.
  • Indirectly, each message is associated with the brand and style through the product.

Now about the use cases:

  • Please note: If you are viewing a single object by id, then a selection of 1-2 related objects is not really a big waybill.

  • List:. When you need to return a large set of objects, each object needs an additional request to get related objects. This is a performance issue. This is usually reduced by processing the "pages" of the result set at a time, say, 20 records per query. Suppose you request 20 products (using skip and limit ). For 20 products, you retrieve two id arrays, one of the styles mentioned and the other brands mentioned. You fulfill 2 additional queries using $in:[ids] , get brand and style objects and place them in the result set. These are 3 requests per page. Users can request the next page when scrolling down, etc.

  • Search: You want to search for products, but also want to specify the brand name and style name. Unfortunately, the product model contains only identifiers of style and brand. The same problem with finding messages with the brand and product. A popular solution is to keep a separate “search index”, a kind of table that stores data exactly as it will search, with all the search fields (such as brand name, style name) in one place. Maintaining such search collections in mongodb manually can be a pain. Here is ElasticSearch . Since you are already using mongoose, you can simply add mongoosastic to your models. ElasticSearch has more search capabilities than the database storage engine offers.

  • Additional speed: There is still room for acceleration: caching. Attach mongoose-redis-cache and frequently repeat repeated requests in Redis memory, reducing the load on mongodb.

  • Twitter as channels: Now, if all messages are publicly available, listing them in chronological order for users is a trivial request. However, everything changes when you enter the functions of the "social network". Then you need to list the “activity channels” of friends and followers. There's some wisdom about social inboxes and fan-out listings on the mongodb blog .

The moral of the story is that not all use cases have only db schema query solutions. Scalability is one such case. That is why other tools exist.

+6
source share

All Articles