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

时间:2017-03-23 14:40:20

标签: javascript mongodb parse-platform parse-server

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

首先,这是我的数据库的架构: enter image description here

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

我想要实现的目标是创建一个以userId为输入并返回城市列表的功能按朋友数量排序

这是我的代码,直到现在

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中找到加入两个查询的方法吗?

1 个答案:

答案 0 :(得分:2)

Parse目前不支持聚合查询。这是一个如何使用js sdk api执行此操作的示例。如果你很好奇,为了确保这个工作,在我检出的parse-server repo版本中,我在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);
  });
});