MongoDB query optimization

I want to get some data from my User model, which looks like this:

var userSchema = new mongoose.Schema({
  email: { type: String, unique: true, lowercase: true },
  password: String,

  created_at: Date,
  updated_at: Date,

  genre : { type: String, enum: ['Teacher', 'Student', 'Guest'] },
  role : { type: String, enum: ['user', 'admin'], default: 'user' },
  active : { type: Boolean, default: false },

  profile: {
    name : { type: String, default: '' },
    headline : { type: String, default: '' },
    description : { type: String, default: '' },
    gender : { type: String, default: '' },
    ethnicity : { type: String, default: '' },
    age : { type: String, default: '' }
  },

  contacts : {
    email : { type: String, default: '' },
    phone : { type: String, default: '' },
    website : { type: String, default: '' }
  },

  location : {
    formattedAddress : { type: String, default: '' },
    country : { type: String, default: '' },
    countryCode : { type: String, default: '' },
    state : { type: String, default: '' },
    city : { type: String, default: '' },
    postcode : { type: String, default: '' },
    lat : { type: String, default: '' },
    lng : { type: String, default: '' }
  }
});

On the main page, I have a filter for a location where you can view users from a country or city.

All fields also contain the number of users:

United Kingdom
  All Cities (300)
  London (150)
  Liverpool (80)
  Manchester (70)
France
  All Cities (50)
  Paris (30)
  Lille (20)
Nederland
  All Cities (10)
  Amsterdam (10)
Etc...

This is on the main page, then I have student and teacher pages where I want to have information only about how many teachers exist in these countries and cities ...

What I'm trying to do is create a query to MongoDB to retrieve all this information with a single query.

At the moment, the request looks like this:

User.aggregate([
    { 
      $group: { 
        _id: { city: '$location.city', country: '$location.country', genre: '$genre' },
        count: { $sum: 1 }
      }
    },
    {
      $group: { 
        _id: '$_id.country',
        count: { $sum: '$count' },
        cities: { 
          $push: { 
            city: '$_id.city', 
            count: '$count'
          }
        },
        genres: {
          $push: {
            genre: '$_id.genre',
            count: '$count'
          }
        }
      }
    }
  ], function(err, results) {
    if (err) return next();
    res.json({ 
        res: results
    });
  });

The problem is that I do not know how to get all the necessary information.

  • I do not know how to get the total number of users in each country.
  • .
  • .
  • , , .

Mongo?

:

promises 2, 3 Mongo:

getSomething
.then(getSomethingElse)
.then(getSomethingElseAgain)
.done

, , : , 5000/10000 ?

, , , / MongoDB.

+4
1

, " " , . , , "" , , .

MongoDB , , - . , , Solr ElasticSearch.

, , , . , , :

 {
     "otherData": "something",
     "facets": [
         "country:UK",
         "city:London-UK",
         "genre:Student"
     ]
 }

, "factets" - , . . :

User.aggregate(
    [
        { "$unwind": "$facets" },
        { "$group": {
            "_id": "$facets",
            "count": { "$sum": 1 }
        }}
    ],
    function(err,results) {

    }
);

$match:

User.aggregate(
    [
        { "$match": { "facets": { "$in": ["genre:student"] } } },
        { "$unwind": "$facets" },
        { "$group": {
            "_id": "$facets",
            "count": { "$sum": 1 }
        }}
    ],
    function(err,results) {

    }
);

:

{ "_id": "country:FR", "count": 50 },
{ "_id": "country:UK", "count": 300 },
{ "_id": "city:London-UK", "count": 150 },
{ "_id": "genre:Student": "count": 500 }

, "" "", "", "-".

- . BSON 16 , ( ) .

- , " " , . .count():

User.count({ "facets": { "$in": ["genre:Student"] } },function(err,count) {

});

, "" , " ", " " " " "" .

, , , .


- , . . , $in $all "" "" .

, , .

. , , , . RDBMS-, , , - .

MongoDB MongoDB, . mongoconnector .

+8

Source: https://habr.com/ru/post/1570437/


All Articles