Mongo使用键嵌套查询

时间:2015-09-21 15:50:38

标签: mongodb

需要有关MongoDB嵌套查询的帮助。下面是我的mongo系列。

偏好收集

{
    "_id" : "user123",
    "preferences" : {
        "product-1" : {
            "frequency" : "Weekly",
            "details" : {
                 "email" : {
                    "value" : "On"
                }
            }
        },
        "product-2" : {
            "preferencesFor" : "mpc-other",
            "preferencesForType" : "Product",
            "details" : {
                "email" : {
                    "value" : "Off"
                }
            }
        },
        "product-3" : {
            "preferencesFor" : "mpc-other",
            "preferencesForType" : "Product",
            "details" : {
                "email" : {
                    "value" : "On"
                }
            }
        }
    }   
}

产品系列

{
    "_id" : "product-1",
     "name" : "Geo-Magazine" 
}
{
    "_id" : "product-2",
     "name" : "History-Magazine"
}
{
    "_id" : "product-3",
     "name" : "Science-Magazine"   
}

product-1,product-2 ...是Map的关键。 密钥存储在另一个集合Product Collection中。 我可以创建嵌套查询来交叉引用另一个表中的产品密钥吗? 我需要下表格式的输出。请建议。

  

user123 product-1 email On

     

user123 product-2 email Off

     

user123 product-3 email On

我尝试过以下但无法获得结果。请建议。

var cursor = db.productSummary.find();   
while(cursor.hasNext()){
    var sku = cursor.next()._id;
    var skuCol = "preferences."+sku+".details.email";
    var skuVal = "preferences."+sku+".details.email.value";
 db.marketingPreferences.find( {}, {_id:1, skuCol:1, skuVal:1});     
}

3 个答案:

答案 0 :(得分:0)

MongoDB和普通SQL DB之间存在差异。首先,当您查询MongoDB集合时,它不会像在SQL数据库中那样返回行。你在这里得到的是一个类似于JSON的文档。

此外,当您使用preferences.product-1.details.email : 1时,它不会返回“电子邮件”字样,而是会返回值,即。 {"value" : "On" }

使用此:db.preference.find({},{"_id":1,"preferences.product1.details.email.value":1})

您将能够获得两个user123On的详细信息,您可以从之前的查询中获得product-1。您可以将这些值存储在变量中并继续打印以获取所需的表。此外,您还需要另一个光标来存储您将要执行的第二个第二个查询的结果。

如果是单一独立查询,那么您的查询将产生什么:

> db.preference.find({},{"_id":1,"preferences.product1.details.email.value":1}) .pretty()

{
"_id": "user123",
"preferences": {
    "product-1": {
        "details": {
            "email": {
                "value": "On"
            }
        }
    }
}
}

答案 1 :(得分:0)

public static void test(){
        MongoCollection<Document> collection = getDatadase().getCollection("product");
        MongoCollection<Document> pref = getDatadase().getCollection("pref");

        List<Document> allDocList =  collection.find().into(new ArrayList<Document>());
        for(Document doc:allDocList){
            System.out.println(doc.get("_id"));
            String preferences = doc.get("_id")+"";
            String sku = "$preferences."+preferences+".details.email.value";

            Document aggregation = new Document().append("$project", new Document().append("_id", 1).append("value", sku));
            List<Document> pipeline = new ArrayList<Document>();
            pipeline.add(aggregation);

            List<Document> aggList = pref.aggregate(pipeline).into(new ArrayList<Document>());

            for(Document doc1:aggList){
                System.out.println(doc1.append("preferences", preferences));
            }
        }
    }

这将返回 产物-1

文档{{_ id = user123,value = On,preferences = product-1}}

产物-2

文档{{_ id = user123,value = Off,preferences = product-2}}

产物-3

文档{{_ id = user123,value = On,preferences = product-3}}

答案 2 :(得分:0)

> var myCursor = db.productSummary.find();
> while(myCursor.hasNext()){   
var sku = myCursor.next()._id;    
var skuCol = "preferences."+sku+".details.email";    
var skuVal = "$preferences."+sku+".details.email.value";    
var result = db.marketingPreferences.aggregate([{"$project":{"_id":1,value:skuVal,preferences:{$literal: sku}}}],{allowDiskUse: true});
    while(result.hasNext()){ 
        printjson(result.next());    
    }      
}

Result 

{ "_id" : "user123", "preferences" : "product-1", "value" : "On" }

{ "_id" : "user123", "preferences" : "product-2", "value" : "Off" }

{ "_id" : "user123", "preferences" : "product-3", "value" : "On" }