Mongodb找到最佳匹配

时间:2013-04-07 13:51:26

标签: node.js mongodb mongoose recommendation-engine

我想构建一个返回DB中最佳匹配文档的查询。

即我想找到一份包含以下字段的文件 - “动物”:“狗” “颜色”:“棕色” “模式”:“点” “尺寸”: “小”

如果没有包含所有上述fiels及其对应值的文档,我希望查询返回最佳匹配。 f.e {“animal”:“dog”,“color”:“brown”,“size”:“small”}

我可以在mongo db中实现递归查询吗?如果是这样,怎么样? 我应该使用mapReduce,如果是这样,怎么样? 人们可以将这个问题更多地视为一个推荐系统问题,我希望在最适合给定值的项目(文档)上推荐,我很感激,如果有人知道实现上述的好方法

我正在使用mongodb mongoose和nodejs。

谢谢。

2 个答案:

答案 0 :(得分:1)

我不确定递归查询的性能影响,但这样的事情应该有效。它从查询中删除最后一个属性,如果未找到匹配项则再次尝试:

var AnimalSchema = new mongoose.Schema({
    atype: { type: String },
    color: {type:String},
    pattern: {type:String},
    size : {type:String}
});

var Animal = mongoose.model('Animal',AnimalSchema);

//test data
//var dalmation = new Animal({
//    atype:'dog',
//    color: 'black and white',
//    pattern: 'spots',
//    size: 'big'
//});

//dalmation.save(function(err){
//    var yorkie = new Animal({
//        atype:'dog',
//        color:'brown',
//        pattern:'mixed',
//        size:'small'
//    });
//    yorkie.save(function(yer){
//         bestMatch({'atype':'dog','size':'big','color':'brown'},function(err,animal){
//             console.log(err,animal);
//         })
//    });
//});

function bestMatch(params,cb){
    Animal.findOne(params,function(err,animal){
        if (err || !animal){
           var keys = Object.keys(params);
           if (keys.length){
               delete params[keys.pop()];
               bestMatch(params,cb);
           }else{
               cb('No matches',null);
           }
        }else{
            cb(null,animal);
        }
    });
}

bestMatch({'atype':'dog','size':'big','color':'brown'},function(err,animal){
    console.log(err,animal);
});

答案 1 :(得分:0)

鉴于您似乎只搜索文本字段,一种可能性是在MongoDB 2.4中使用新的(当前“实验性的”)text search feature。这允许您在一个或多个字段上创建全文索引,包括field weighting以获取相关性。

例如:

db.collection.ensureIndex(
    // Fields to index
    {
        animal:  "text",
        color:   "text",
        pattern: "text",
        size:    "text"
    },

    // Options
    {
        name: "best_match_index",

        // Adjust field weights (default is 1)
        weights: {
            animal: 5,  // Most relevant search field
            size:   4   // Also relevant
       }
    }
)

Results将按照与相关字段权重相关的评分顺序返回。

请注意,搜索关键字也是stemmed,因此如果您期望完全匹配,这可能会产生一些意想不到的结果。您可以将您的字词放在双引号中,以便利用phrase matching进行更具体的匹配。