如何使用mongoDB java驱动程序在matlab中实现MongoDB $ filter函数

时间:2017-06-25 19:43:05

标签: mongodb aggregation-framework mongo-java-driver

我刚开始学习mongoDB,这是我的问题:在我的Mongo数据库中,我有一个包含以下项目的集合:

{
    "Common Name": "Tom",
    "Country": "Germany",
    "apperiance":   [{
                        "colour": "white",
                        "hair": "long",
                        "height": 180,
                        "weight": [100, 90],
                        "weights":  {
                                        "weights1": 99999,
                                        "weights2": 100, 
                                        "weights3": 99999, 
                                        "weights4": 99999, 
                                        "weights5": 99999, 
                                        "weights6": 90
                                                    }
                     },
                    {
                       "colour": "white",
                       "hair": "short",
                       "height": 170,
                       "weight": [95, 90],
                       "weights":   {
                                        "weights1": 99999,
                                        "weights2": 95, 
                                        "weights3": 99999, 
                                        "weights4": 99999, 
                                        "weights5": 99999, 
                                        "weights6": 90
                                    }
                     }]
    }

如果我在mongoDB中编写以下代码:

db.collection1.aggregate([
   {
        $match: {
                    $and:[
                            {"apperiance.weight": 100},
                            {"apperiance.height":180},
                            {"apperiance.hair":"long"}
                        ]
                }
    },
   {
        $project: {
         "apperiance": {
            $filter: {
               input: "$apperiance",
               as: "apperiances",
               cond: { $and:[{$eq: [ "$$apperiances.height", 180 ]},{$eq: [ "$$apperiances.hair", "long" ]}] }
            }
         }
       }
     },
     {
        $project: {"apperiance.weights":1, "_id":0}                     
     }
]).pretty()

我得到了一个理想的结果:

{
        "apperiance" : [
                {
                        "weights" : {
                                "weights1" : 99999,
                                "weights2" : 100,
                                "weights3" : 99999,
                                "weights4" : 99999,
                                "weights5" : 99999,
                                "weights6" : 90
                        }
                }
        ]
}

我想通过mongoDB java驱动程序在matlab中实现同样的功能。我现在所拥有的是matlab中流动的代码:

%% call java driver
javaaddpath('mongo-java-driver-3.4.2.jar');

import com.mongodb.*;

%% connect to Mongo client
m   = MongoClient('localhost', 27017);
% handle to database              
db  = m.getDB('test');                                   
% handle to collection 
col = db.getCollection('collection1') ;                 

%% match
%first match
mtch_pogoj1 = BasicDBObject('apperiance.height', ...              
    BasicDBObject('$eq',180)) ;                     

%second match
mtch_pogoj2 = BasicDBObject('apperiance.weight', ...        
    BasicDBObject('$eq',100)) ;                     

%collect both matches in new variable pogoj
pogoj = BasicDBList(); 
pogoj.add(mtch_pogoj1);
pogoj.add(mtch_pogoj2);
%both matches need to be considered with $and statement
mtch_cel = BasicDBObject('$and', pogoj);
% pipe-line command match, full query
mtch1  = BasicDBObject('$match',  mtch_cel) ;             

%% projection
% start specifying projection
prj1a = BasicDBObject() ; 
% do not keep id                             
prj1a.put('_id',0) ; 
% keep 'weights'                                   
prj1a.put('apperiance.weights',1) ;                           

% pipe-line command project
prj1  = BasicDBObject('$project',  prj1a) ;

%% define pipeline
% start specifying pipeline list 
aggr_list = BasicDBList();                                                      
aggr_list.add(mtch1);                                   % add first match 
aggr_list.add(prj1);                                    % add projection

%% do the actual aggregation according pipeline
% create aggregation output
ao  = col.aggregate(aggr_list); 
% cursor to results of the aggregation                        
cur = ao.results().iterator();                          
fprintf('show aggregation results\n')
mm_cursor_showcontents( cur ) ;

不幸的是,matlab代码输出所有权重:

 show aggregation results
{ "apperiance" : [ { "weights" : { "weights1" : 99999.0 , "weights2" : 100.0 , "weights3" : 99999.0 , "weights4" : 99999.0 , "weights5" : 99999.0 , "weights6" : 90.0}} , { "weights" : { "weights1" : 99999.0 , "weights2" : 95.0 , "weights3" : 99999.0 , "weights4" : 99999.0 , "weights5" : 99999.0 , "weights6" : 90.0}}]}

我想在子文档中仅输出所需的权重,其中“height”:180和“weight”:[100,90]。我知道我需要实现$ filter函数,但我无法弄清楚如何使用mongo java驱动程序。

编辑: 我按照链接的答案中的建议实现了$ filter函数。

%%filter function
filterExpression = BasicDBObject() ;                               
filterExpression.put('input', '$apperiance');
filterExpression.put('as', 'apperiances');
equal=(BasicDBObject('$$apperiances.height', 180));
filterExpression.put('cond', BasicDBObject('$eq',equal));
filter= BasicDBObject('$filter', filterExpression);

project1 = BasicDBObject() ;
project1.put('apperiance',filter);
project_full  = BasicDBObject('$project',  project1)

project_full输出现在与我在mongodb db shell中编写的输出相同。但是如果我将上面的代码添加到aggr_list.add(project_full)并尝试在matlab中执行完整代码,我会收到以下错误。

  

发生了Java异常:com.mongodb.MongoCommandException:Command   失败,错误168:'无法识别的表达式   服务器localhost:27017上的“$$ apperiances.height”。完整的回应   是{“ok”:0.0,“errmsg”:“无法识别的表达式   '$$ apperiances.height'“,”code“:168,”codeName“:   “InvalidPipelineOperator”}

我也试图像这样实现代码

filterExpression.put('cond', BasicDBObject('$eq',Arrays.<Object> asList('$$apperiances.height', 180)));

但声明Arrays。 matlab无法识别asList。我陷入困境,不知道如何在matlab中实现它以使其工作。

如果有人可以帮助我找到问题的解决方案或解决方法,我将非常感激。

0 个答案:

没有答案