我刚开始学习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中实现它以使其工作。
如果有人可以帮助我找到问题的解决方案或解决方法,我将非常感激。