简体   繁体   中英

How to design the user/order/shipping model in mongo for a e-commerce app?

Every order has a shipping info and every user has several shipping addresses. This is my design:

User:
   ...
   defaultAddress: ObjectId
   ...
Address:
   ...
   ...   
   ...
Order:
   ...
   shipping: ObjectId  
   ...

Here are my questions:

  1. Is it reasonable to use a reference for shipping in Order Model, or just embed the entire Address object.
  2. Every time add a new address from App, Is there any better way to check if it is already exist in mongodb?
  3. Should I keep a defaultAddress key in User Model, or should I just use a array to keep all the address object?

Thanks very much.

Addresses bind closely to Users, so make Addresses an array inside Users.

Depending on your overall audit / revisioning data architecture, you may wish to copy the address into the Order doc upon creation to create an unambiguous record of where it went. Having Order reference back into User and address implies you cannot change the address; you would have to mark it as no longer active but not deleted . Note you do not have to laborious copy all the fields; you can treat the selected address as an object, something like:

var addr = get addr;  // from DB or wherever; any shape with any number of subfields is fine.                                 

db.order.insert({orderId:"someID", date:new ISODate(), shippingAddress: addr});

To prevent dupes, it is a matter of looking up the info in the array -- but of course caveats apply such as making sure you canonicalize case, strip white space, remove unnecessary punctuation, etc. etc. Let's assume you have street , city , and state as the matchable fields:

{
    "user":"U1",
    "addrs": [
        {street: "20 Pine Ln", city: "Smallville", state: 'NM'},
        {street: "16 Elm Ln", city: "Denver", state: 'CO'},
        {street: "77 Sunshine Pkway", city: "Denver", state: 'CO'},
    ]
}

After grooming the input from app, assume we have a target lookup doc like this. Note: We do NOT have to create the doc with fields in a particular order.

var target = {city: "Denver", state: 'CO', street: '16 Elm Ln'};

The lookup is simple. Since addrs is an array, the match will dive into and iterate over the array. The $elemMatch operator ensures that ALL fields in the candidate match those in the target.

db.foo.aggregate([
    {$match: {user:'U1', "addrs":{$elemMatch: target} }}
]);

If no records are found, then this is a new address.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM