2017-03-23 69 views
0

我使用parse server + MongoDB的的後端,我需要幫助創建配合物查詢:創建配合物解析服務器或MongoDB的查詢

首先這裏是我的數據庫架構: enter image description here

friends模型代表兩個用戶之間的友誼。 每個usercity

我試圖做到的,是創建採取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({}) 

} 

所以probleme是我想不通的解析或MongoDB中的方式方法來加入這兩個疑問?

回答

2

解析此時不支持聚合查詢。下面是一個如何使用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); 
    }); 
}); 
+0

謝謝!所以你得到所有用戶朋友的名單,然後循環的朋友列表,並作出城市的數量,它? 另外如果用戶有成千上萬的朋友,它會太複雜,因爲解析每頁不能處理超過1000個項目? – Chlebta

+0

Parse.Query.each()沒有限制。它會貫穿所有的。如果有成千上萬或數百萬的話,問題可能就是超時連接。 替代方案是在'Friend'類上創建一個'beforeSave'鉤子並將聚合保存在保存中,而不是在需要時查找它。所以你可以有一個FriendCityCount類,它有userid,city,count作爲列..... –

+0

我認爲,但這添加了另一個表來處理,其他功能...它是有線爲什麼NoSql不支持加入查詢 – Chlebta

相關問題