首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >保存用户联系人的MongoDB架构优化

保存用户联系人的MongoDB架构优化
EN

Stack Overflow用户
提问于 2020-01-17 13:34:00
回答 4查看 1.1K关注 0票数 3

我想设计一个用于存储用户联系人的架构。

下面是我现有的模式:

用户模式

代码语言:javascript
复制
_id : ObjectId("5c53653451154c6da4623a77"),
name : “something”,
email : “something”,
password : “something”,

配置文件模式

代码语言:javascript
复制
"_id" : ObjectId("5c53653451154c6da4623a88"),
user_id - ref
mobile : “something”,
company” : “something”,
designation : “something”,
website : “something”,
social: {
    youtube: {
        type: String
    },
    twitter: {
        type: String
    },
    facebook: {
        type: String
    },
    linkedin: {
        type: String
    },
    instagram: {
        type: String
    }
}

我可以想到接触模式的两种方法,但两者都有一些缺点:

优先逼近

代码语言:javascript
复制
"_id" : ObjectId("5c53653451154c6da4623a99"),
user_id - ref,
"contacts": [
   {
    name : “something”,
    company : “something”,
    designation : “something”,
    website : “something”,
    social: { something },
    mobile : “something”
   },
   {
    name : “something”,
    company : “something”,
    designation : “something”,
    website : “something”,
    social: { something },
    mobile : “something”
    },
    ...
]

上述结构的问题在于,当用户更新其配置文件时,联系人字段无法获得更新的值。但是,在这种方法中,很容易查询和检索特定用户的所有联系人并将响应发回。

第二次逼近

代码语言:javascript
复制
"_id" : ObjectId("5c53653451154c6da4623a99"),
user_id : ref,
contacts: [
    profile_id,
    profile_id,
    profile_id,
    profile_id,
    profile_id,
    profile_id,
    ...
]

在此结构中,联系人在用户更新其配置文件时具有更新的用户值。但是这里的问题是,在查询时,我必须从联系人模式中获取配置文件id,然后查询配置文件模式并将值作为响应返回给客户端。

当有30K-50K联系人时会发生什么?我需要查询DB 50K次吗?还是有更好的方法?

在node.js上构建,使用猫鼬。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2020-01-17 15:44:40

基本上,您有一个需要关系数据库的场景。但你也可以在mongo中实现这一点。

您需要使用填充猫鼬的。用你的第二个方法。存储配置文件ids的地方。

代码语言:javascript
复制
User.find({_id: '5c53653451154c6da4623a77'}).populate({
path:'profiles',
options: {
    limit: 10,
    skip: 0
}}).exec();

猫鼬种群

此查询将返回相关配置文件。如果你有像50K这样的数据。您必须将数据限制在一个请求中。

注意:每个文档的Mongodb限制为16 is。不可能存储这么多数据.

所以,重新考虑一下你的数据库。

票数 1
EN

Stack Overflow用户

发布于 2020-01-17 14:56:44

如果我对你的理解是正确的,我认为你正确地识别了每个选项的优缺点。现在你必须决定什么对你的具体案件有意义。选项1很容易获取,但更新和保持与Profile的同步却很繁琐。选项2具有更多的规范化数据,更适合更新,但需要更多查询才能检索。所以你得问自己一些问题。

  • 拥有规范化数据对你来说有多重要?
  • 您的ProfileContact模式的大小将如何比较?你会有更多的个人资料吗?明显少了?数量级?
  • 会发生更多的事情--有人更新他们的个人资料,或者有人查询联系人?还要多少钱?数量级?
  • 深入研究你的前两个答案--做一些估计,如果有必要的话,甚至是粗略的,然后做一些数学,看看什么可能更有意义。

例如,如果每个用户有10,000个联系人,那么选项1将为您提供一个更大的文档,它可以在一个查询中收集所有联系人和概要文件。如果您的用户只更新他们的配置文件,例如,平均每月一次,但是您需要每天查询几次联系人,这可能是更好的选择。但是,如果您的用户喜欢每天更新他们的配置文件,并且需要每周查询一次联系人,那么选项2可能更有意义。

最后,这是一个非常特定于您的场景的设计选择。祝好运!

票数 1
EN

Stack Overflow用户

发布于 2020-01-17 14:23:57

有2种模式,一种是针对用户的,另一种是针对订单的。一个用户可以创建多个订单,如您的联系人。

用户-

代码语言:javascript
复制
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const bcrypt = require("bcryptjs");

const userSchema = new Schema(
  {
    firstName: {
      trim: true,
      type: String,
      required: [true, "firstName is required!"],
      validate(value) {
        if (value.length < 2) {
          throw new Error("firstName is invalid!");
        }
      }
    },
    lastName: {
      trim: true,
      type: String,
      required: [true, "lastName is required!"],
      validate(value) {
        if (value.length < 2) {
          throw new Error("lastName is invalid!");
        }
      }
    },
    email: {
      unique: [true, "Email already registered"],
      type: String,
      required: [true, "Email is required"]
    },
    password: {
      trim: true,
      type: String,
      require: [true, "Password is required"],
      validate(value) {
        if (value.length < 6) {
          throw new Error("Password should be atleast 6 characters");
        }
      }
    },
    mobile: {
      trim: true,
      unique: [true, "Mobile Number already available"],
      type: String,
      required: [true, "Mobile Number is required"],
      validate(value) {
        if (value.length !== 10) {
          throw new Error("Mobile Number is invalid!");
        }
      }
    },
    gender: {
      trim: true,
      type: String,
      enum: [
        "Male",
        "Female"
      ],
      required: [true, "Password is required"],
    },
    dob: {
      trim: true,
      type: Date,
      required: [true, "DOB is required"],
    },
    Address: {
      address: {
        trim: true,
        type: String,
        require: [true, "Owner Address is required"]
      },
      city: {
        trim: true,
        type: String,
        require: [true, "Owner Address City is required"]
      },
      state: {
        trim: true,
        uppercase: true,
        type: String,
        require: [true, "Owner Address State is required"]
      },
      pin: {
        trim: true,
        uppercase: true,
        type: Number,
        require: [true, "Owner Address Pin is required"],
        validate(value) {
          if (!(value >= 100000 && value <= 999999)) {
            throw new Error("Pin is invalid!");
          }
        }
      }
    }
  },
  {
    timestamps: true
  }
);

const Users = mongoose.model("Users", userSchema);

module.exports = Users;

命令-

代码语言:javascript
复制
const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const orderSchema = new Schema({
  userId: {
    trim: true,
    type: Schema.Types.ObjectId,
    ref: "users",
    required: [true, "User ID is required"]
  },
  dateOfOrder: {
    trim: true,
    type: Date,
    required: [true, "Date of Order is required"],
  },
  dateOfMeasurement: {
    trim: true,
    type: Date,
  },
  dateOfTrail: {
    trim: true,
    type: Date,
  },
  dateOfDelivery: {
    trim: true,
    type: Date,
  },
},


  {
    timestamps: true
  });

const Orders = mongoose.model("Orders", orderSchema);

module.exports = Orders;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59788454

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档