如何使用自定义排名算法查找匹配的元素

时间:2018-04-29 22:46:35

标签: javascript mongodb mongoose

我需要计算每个帐户的排名。排名取决于请求该方法的帐户。

var account; // assumed to be one requesting the method
const allMatches = Account.find({
    $or: [
            { argA: account.argA },
            { argB: account.argB },
            { argC: account.argC }
        ],
        _id: {$ne: account._id}
    });  
const getRank = (item) => {
    let rank = 0;
    if (item.argB === account.argB) {
        rank += 3;
    }
    if (item.argA === account.argA) {
        rank += 2;
    }
    if (item.argC === account.argC) {
        rank += 1;
    }
    return rank;
};
const compare = (a,b) => {
    const rankA = getRank(a);
    const rankB = getRank(b);
    if (rankA === rankB) return 0;
    return rankA > rankB ? 1: -1;
}
// use the compare method 
allMatches.sort(compare);
account.set({match : allMatches[0]['id']});

但是,我不能像这样使用sort方法,因为它需要一个对象或一个字符串。 我需要一些帮助才能朝着正确的方向前进。

例如 - 如果系统中有3个帐户

A1 - {argA: 'A', argB: 'B', argC: 'C'}
A2 - {argA: 'D', argB: 'B', argC: 'F'}
A3 - {argA: 'G', argB: 'H', argC: 'C'}

现在如果A1需要找到匹配 -

Rank score with A2 is = 3 // argB is same
Rank score with A3 is = 1 // argC is same

因此A1将与A2匹配,这就是我所需要的。

1 个答案:

答案 0 :(得分:0)

您可以使用.aggregate()

“对数据库进行排序”
let results = await Account.aggregate([
  { "$match": { 
    "$or": [
        { "argA": account.argA },
        { "argB": account.argB },
        { "argC": account.argC }
    ],
    "_id": { "$ne": account._id}
  }},
  { "$addFields": {
    "rank": {
      "$sum": [
        { "$cond": [{ "$eq": ["$argA", account.argA] }, 3, 0 ] },
        { "$cond": [{ "$eq": ["$argB", account.argB] }, 2, 0 ] },
        { "$cond": [{ "$eq": ["$argC", account.argC] }, 1, 0 ] }
      ]        
    }
  }},
  { "$sort": { "rank": -1 } }
  /* 
   * Add $skip and $limit for paging if needed
  { "$skip": 0 },
  { "$limit": 25 },
  */
])

同时注意到Account.aggregate()Account.find()实际上返回Promise,因为该方法是异步的,因此您需要await.then()或提供Account.aggregate([ { "$match": { "$or": [ { "argA": account.argA }, { "argB": account.argB }, { "argC": account.argC } ], "_id": { "$ne": account._id} }}, { "$addFields": { "rank": { "$sum": [ { "$cond": [{ "$eq": ["$argA", account.argA] }, 3, 0 ] }, { "$cond": [{ "$eq": ["$argB", account.argB] }, 2, 0 ] }, { "$cond": [{ "$eq": ["$argC", account.argC] }, 1, 0 ] } ] } }}, { "$sort": { "rank": -1 } } /* * Add $skip and $limit for paging if needed { "$skip": 0 }, { "$limit": 25 }, */ ]).then( result => /* do something */ ) 回调,取决于您的首选风格:

"rank"

该承诺/回调解决方案是您代码中的基本错误。

但一般情况下,您可能希望计算服务器上的int pids[N]; for(int i = 0; i < N; i++){ pids[i] = fork(); if(pids[i]==0){ //do something break; } } ,以便在较大的结果集上启用分页,这比尝试排序要聪明得多 在结果数组中。