创建复杂的解析服务器或 mongodb 查询

Create a complexe parse server or mongodb query

我正在使用 parse server + mongodb 作为后端,我需要帮助来创建复杂的查询:

首先这是我的数据库的架构:

friends模型代表两个用户之间的友谊。 每个 user 都有一个 city

我想要实现的是创建函数,将 userId 作为输入和 return 城市列表 按朋友数量排序 .

这是我到目前为止的代码

function getCities(userId) {

  //This query allow to count number of friends in a given city 
  var innerQuery1 = new Parse.Query(Friends);
  innerQuery1. equalTo("user1", userId);

  var innerQuery2 = new Parse.Query(Friends);
  innerQuery2.equalTo("user2", userId);

  countFriendsQueryInCity = Parse.Query.or(innerQuery1, innerQuery2);
  countFriendsQueryInCity.equalTo("city", cityId)
  countFriendsQueryInCity.count({..})

  //This to get all cities
  var query = new Parse.Query(City);
  query.find({})

}

所以问题是我无法在解析或 mongodb 中想出一种方法来加入这两个查询?

Parse 目前不支持聚合查询。这是一个如何使用 js sdk api 执行此操作的示例。如果你很好奇,为了确保这有效,在我检出的解析服务器版本中,我在 spec 目录中创建了一个 spec 文件,其中包含以下所有内容,然后我只关注测试 (通过在 'describe').

前面放置一个 'f'
/**
 * Return a sorted list of cities with count of friends in that city
 *
 * @param userId id of the user to build the list for
 * @returns an array of city, count pairs sorted descending
 */
const getCities = function getCities(userId) {
  const aggregation = {};
  const userPointer = new Parse.Object('Person').set('objectId', userId);
  return new Parse.Query('Friend')
    .equalTo('user1', userPointer)
    .include('user2.city')
    .each((friendship) => {
      const city = friendship.get('user2').get('city').get('name');
      if (aggregation[city]) {
        aggregation[city]++
      }
      else {
        aggregation[city] = 1;
      }
    })
    .then(() => {
      const sortable = [];
      for (const city in aggregation) {
        sortable.push([city, aggregation[city]]);
      }
      return sortable.sort((a, b) => b[1] - a[1]); // desc
    });
}


// the unit test for the function above....
fdescribe('play with aggregations', () => {
  it('should count friends by city and order desc', (done) => {

    // create cities
    const ny = new Parse.Object('City').set('name', 'ny');
    const sf = new Parse.Object('City').set('name', 'sf');

    // create some people to befriend
    const people = [
      new Parse.Object('Person').set('city', ny),
      new Parse.Object('Person').set('city', sf),
      new Parse.Object('Person').set('city', sf),
      new Parse.Object('Person').set('city', sf),
    ];

    // the object of these friendships
    const friendee = new Parse.Object('Person').set('city', sf);

    // make the friendships
    const friends = people.map(person =>
      new Parse.Object('Friend')
        .set('user1', friendee)
        .set('user2', person));

    // just saving the friends will save the friendee and cities too!
    Parse.Object.saveAll(friends)
      // all saved, now call our function
      .then(() => getCities(friendee.id))
      .then((result) => {
        const lastResult = result.pop();
        const firstResult = result.pop();
        expect(lastResult[0]).toBe('ny');
        expect(lastResult[1]).toBe(1);
        expect(firstResult[0]).toBe('sf');
        expect(firstResult[1]).toBe(3);
        done();
      })
      .catch(done.fail);
  });
});