使用属性数组查询Mongoose Hash Map?

时间:2016-04-02 23:48:32

标签: javascript node.js mongodb mongoose

我有一个名为csgoItems的mongoose文档和模式,如下所示:

{
    "_id": {
        "$oid": "56ff8fb815ad7ecdede3bc3c"
    },
    "csgo_number": 1,
    "last_updated": 1459589048324,
    "items": {
        "Shadow Daggers | Urban Masked (Well-Worn)": {
            "market_hash_name": "Shadow Daggers | Urban Masked (Well-Worn)",
            "sale_price": 134.29
        },
        "Shadow Daggers | Urban Masked (Minimal Wear)": {
            "market_hash_name": "Shadow Daggers | Urban Masked (Minimal Wear)",
            "sale_price": 108.3
        },
        "Shadow Daggers | Urban Masked (Field-Tested)": {
            "market_hash_name": "Shadow Daggers | Urban Masked (Field-Tested)",
            "sale_price": 79.73
        },
        "Shadow Daggers | Urban Masked (Battle-Scarred)": {
            "market_hash_name": "Shadow Daggers | Urban Masked (Battle-Scarred)",
            "sale_price": 73.17
        },
        "Shadow Daggers | Stained (Well-Worn)": {
            "market_hash_name": "Shadow Daggers | Stained (Well-Worn)",
            "sale_price": 113.25
        }
    }
}

我正在尝试使用market_hash_names数组来返回只包含那些市场哈希名称的项目列表

var searchItems = ["Shadow Daggers | Stained (Well-Worn)", "Shadow Daggers | Urban Masked (Battle-Scarred)"]

我试过这个

    csgoItems.find({"items": {$in: searchItems}}, function(err, found){
        if(err){
            console.log(err);
        }else{
            console.log(found);
        }

如何实现这些结果?

1 个答案:

答案 0 :(得分:1)

查询无效,因为$in运算符仅适用于数组。

要根据哈希的属性过滤查询结果,您需要使用MongoDB的mapReduce

一个简单的解决方案是:

  1. 定义一个将哈希映射转换为数组的函数

    function hashToArray(hash) {
      return Object.keys(hash).map(function(key) {
        return hash[key];
      });
    }
    
  2. 定义mapReduce查询的选项

    hashToArray函数将用于将items哈希值转换为每个文档的数组。

    var options = {};
    options.map = function (){ 
      emit(this._id, hashToArray(this.items), 1);
    }
    options.reduce = function (key, values){ 
      return values[0];
    }
    
  3. 执行地图缩小并针对结果运行查询

    csgoItems.mapReduce(options, function(err, model, stats) {
      model.find({"items.market_hash_name": {$in: searchItems}},   function(err, foundItems){
        // use the result
      });
    });