azp*_*lic 10 mongodb aggregation-framework
在我的mongoDB书籍集中,我的文档结构如下:
/* 0 */
{
"_id" : ObjectId("50485b89b30f1ea69110ff4c"),
"publisher" : {
"$ref" : "boohya",
"$id" : "foo"
},
"displayName" : "Paris Nightlife",
"catalogDescription" : "Some desc goes here",
"languageCode" : "en",
"rating" : 0,
"status" : "LIVE",
"thumbnailId" : ObjectId("50485b89b30f1ea69110ff4b"),
"indexTokens" : ["Nightlife", "Paris"]
}
Run Code Online (Sandbox Code Playgroud)
我执行以下正则表达式查询以查找具有以"Par"开头的一个indexToken的所有文档:
{ "indexTokens" : { "$regex" : "^Par" , "$options" : "i"}}
Run Code Online (Sandbox Code Playgroud)
如果我只选择要返回的indexTokens字段,如下所示:
{ "indexTokens" : 1}
Run Code Online (Sandbox Code Playgroud)
生成的DBObject是
{ "_id" : { "$oid" : "50485b89b30f1ea69110ff4c"} , "indexTokens" : [ "Nightlife" , "Paris"]}
Run Code Online (Sandbox Code Playgroud)
我想得到的只是与正则表达式匹配的标记/标记(此时我不关心检索文档,我也不需要匹配文档的所有标记)
这是MongoDB v2.2下新的聚合框架的案例吗??
如果是,我如何修改我的查询,以便实际结果如下所示:
{"indexTokens":["巴黎","天堂河","帕尔马"等......]
奖金问题(你有没有代码):我如何使用Java驱动程序?
现在我的java看起来像:
DBObject query = new BasicDBObject("indexTokens", java.util.regex.Pattern.compile("^"+filter+"", Pattern.CASE_INSENSITIVE));
BasicDBObject fields = new BasicDBObject("indexTokens",1);
DBCursor curs = getCollection()
.find(query, fields)
.sort( new BasicDBObject( "indexTokens" , 1 ))
.limit(maxSuggestionCount);
Run Code Online (Sandbox Code Playgroud)
谢谢 :)
编辑:
根据您的回答,我修改了我的JAVA代码如下:
BasicDBObject cmdBody = new BasicDBObject("aggregate", "Book");
ArrayList<BasicDBObject> pipeline = new ArrayList<BasicDBObject>();
BasicDBObject match = new BasicDBObject("$match", new BasicDBObject("indexTokens", java.util.regex.Pattern.compile("^"+titleFilter+"", Pattern.CASE_INSENSITIVE)));
BasicDBObject unwind = new BasicDBObject("$unwind", "$indexTokens");
BasicDBObject match2 = new BasicDBObject("$match", new BasicDBObject("indexTokens", java.util.regex.Pattern.compile("^"+titleFilter+"", Pattern.CASE_INSENSITIVE)));
BasicDBObject groupFilters = new BasicDBObject("_id",null);
groupFilters.append("indexTokens", new BasicDBObject( "$push", "$indexTokens"));
BasicDBObject group = new BasicDBObject("$group", groupFilters);
pipeline.add(match);
pipeline.add(unwind);
pipeline.add(match2);
pipeline.add(group);
cmdBody.put("pipeline", pipeline);
CommandResult res = getCollection().getDB().command(cmdBody);
System.out.println(res);
Run Code Online (Sandbox Code Playgroud)
哪个输出
{ "result" : [ { "_id" : null , "indexTokens" : [ "Paris"]}] , "ok" : 1.0}
Run Code Online (Sandbox Code Playgroud)
这才是天才!
非常感谢 !
cir*_*rus 11
您可以使用2.2聚合框架执行此操作.像这样的东西;
db.books.runCommand("aggregate", {
pipeline: [
{ // find docs that contain Par*
$match: { "indexTokens" : { "$regex" : "^Par" , "$options" : "i"}},
},
{ // create a doc with a single array elemm for each indexToken entry
$unwind: "$indexTokens"
},
{ // now produce a list of index tokens
$group: {
_id: "$indexTokens",
},
},
],
})
Run Code Online (Sandbox Code Playgroud)
或者如果你真的想要没有doc的数组,那么这可能更接近你所追求的;
db.books.runCommand("aggregate", {
pipeline: [
{ // find docs that contain Par*
$match: { "indexTokens" : { "$regex" : "^Par" , "$options" : "i"}},
},
{ // create a doc with a single array elemm for each indexToken entry
$unwind: "$indexTokens"
},
{ // now throw out any unwind's that DON'T contain Par*
$match: { "indexTokens": { "$regex": "^Par", "$options": "i" } },
},
{ // now produce the list of index tokens
$group: {
_id: null,
indexTokens: { $push: "$indexTokens" },
},
},
],
})
Run Code Online (Sandbox Code Playgroud)
小智 5
根据 cirrus 的响应,我建议$unwind首先执行此操作以避免多余的$match. 就像是:
db.books.aggregate(
{$unwind:"$indexTokens"},
{$match:{indexTokens:/^Par/}},
{$group:{_id:null,indexTokens:{$push:"$indexTokens"}}
})
Run Code Online (Sandbox Code Playgroud)
在 Java 中如何做到这一点?您可以使用DBCollection.aggregate(...)MongoDB v2.9.0驱动程序的方法。每个管道操作员,例如。$unwind或$match, 对应于一个DBObject对象。
| 归档时间: |
|
| 查看次数: |
16973 次 |
| 最近记录: |