如何在mongo查询中将对象推送到数组中

时间:2016-10-28 10:00:03

标签: mongodb mongodb-query

我是MongoDB的新手,我想在mongo查询中将对象推送到数组中。

这是我的代码

    String urlString = "http://localhost:8983/solr/gettingstarted";
    SolrClient solr = new HttpSolrClient.Builder(urlString).build();


    Map<String, Object> fieldAttributes = new LinkedHashMap<>();
    fieldAttributes.put("name", "sell-by");
    fieldAttributes.put("type", "tdate");
    fieldAttributes.put("stored", true);

    SchemaRequest.AddField addFieldUpdateSchemaRequest =
            new SchemaRequest.AddField(fieldAttributes);
    SchemaResponse.UpdateResponse addFieldResponse = addFieldUpdateSchemaRequest.process(solr);

在我的项目服务器端控制器中运行上述查询时,出现错误。我试图从查询返回计数,但这也是一个错误。现在我想在mongodb查询中推送对象。我该怎么做?

预期输出

var array = [
    {
        "heading": "Fruits",
        "contents": []
    },
    {
        "heading": "Vegetables",
        "contents": []
    }
];
var mongoquery = { "category.title": "home" };

for(var i=0; i<array.length; i++){
    for(var j=0; j<array[i].contents.length; j++ ){
        Collection.find(mongoquery).count({}, function(err, count){
            var resultantCount = count;
            array[i].contents.push({
                name: 'Apple',
                count: count
            });
        });
    }
}

2 个答案:

答案 0 :(得分:1)

您使用同步和异步代码一起使用。

选中此内容以获得更多理解。

https://blog.risingstack.com/node-hero-async-programming-in-node-js/

此外,如果您想修复代码,我建议您查看此库 http://caolan.github.io/async/docs.html#each

使用该库修复代码,您只需要

async.each(array, function(value, done){
   //now query mongoDB and write result
   Collection.find(mongoquery).count({}, function(err, count){
        if (err) {return done(err);}
        //as we reference to array type this will modify original array so we can just push into contents
        value.contents.push({
            name: 'Apple',
            count: count
        });
        //callback function when all done. Go to next iteration
        done();
    });
}, function(err){
    if(err) {console.log(err);}
   //final callback here after all iterations done.
   console.log(array);
});

希望这有帮助。

答案 1 :(得分:0)

由于不愿意在您的集合中显示一些示例文档,因此我根据相关数组对集合中文档的结构做了一些基本假设。

假设您的收藏品由这种性质的文件组成:

{        
    "category": {
        "title": "home",
        "name": "Fruits"
    },
    "name": "Apple"
},
{        
    "category": {
        "title": "home",
        "name": "Fruits"
    },
    "name": "Orange"
},
{        
    "category": {
        "title": "home",
        "name": "Vegetables"
    },
    "name": "Peas"
}

为了获得所需的结果,您需要运行一个非常高效的aggregation operation,因为它使用MongoDB中的本机运算符,而不是在出现性能问题的循环中执行异步调用。

考虑运行以下管道:

var pipeline = [
    { "$match": { "category.title": "home" } },
    {
        "$group": {
            "_id": {
                "category": "$category.name",
                "name": "$name"
            },
            "count": { "$sum": 1 }
        }
    },
    {
        "$group": {
            "_id": "$_id.category",
            "contents": {
                "$push": {
                    "name": "$_id.name",
                    "count": "$count"
                }
            }
        }
    },
    {
        "$project": {
            "_id": 0,
            "heading": "$_id",
            "contents": 1
        }
    }
];

Collection.aggregate(pipeline, function(err, result) {
    console.log(JSON.stringify(result, null, 4));
});

对假定的样本文档运行上述聚合操作将产生以下结果:

示例输出

[
    {
        "heading": "Fruits",
        "contents": [
            { "name": "Apple", "count": 1 },
            { "name": "Orange", "count": 1 }
        ]
    },
    {
        "heading": "Vegetables",
        "contents": [
            { "name": "Peas", "count": 1 }
        ]
    }
]

更新

如果您使用之前的question中的示例文档

,请从评论跟踪中查看
/* 1 */
{
    "_id" : ObjectId("58133a40c23d8b16b062e86a"),
    "name" : "Tomatos",
    "array" : [ 
        {
            "title" : "Vegetables"
        }
    ],
    "description" : "Vegitables are good to health"
}

/* 2 */
{
    "_id" : ObjectId("58133a40c23d8b16b062e86b"),
    "name" : "Apples",
    "array" : [ 
        {
            "title" : "Fruits"
        }
    ],
    "description" : "Fruits are good to health, vegitables are also good to health"
}

/* 3 */
{
    "_id" : ObjectId("58133a40c23d8b16b062e86c"),
    "name" : "Apples",
    "array" : [ 
        {
            "title" : "Vegetables-home-made"
        }
    ],
    "description" : "Fruits are good to health, vegitables are also good to health"
}

然后考虑运行以下管道以获得所需的结果:

Collection.aggregate([
    { "$unwind": "$array" },
    {
        "$group": {
            "_id": {
                "category": "$array.title",
                "name": "$name"
            },
            "count": { "$sum": 1 }
        }
    },
    {
        "$group": {
            "_id": "$_id.category",
            "contents": {
                "$push": {
                    "name": "$_id.name",
                    "count": "$count"
                }
            }
        }
    },
    {
        "$project": {
            "_id": 0,
            "heading": "$_id",
            "contents": 1
        }
    }
], function(err, result) {
    console.log(JSON.stringify(result, null, 4));
});

示例输出

/* 1 */
{
    "contents" : [ 
        {
            "name" : "Apples",
            "count" : 1
        }
    ],
    "heading" : "Vegetables-home-made"
}

/* 2 */
{
    "contents" : [ 
        {
            "name" : "Apples",
            "count" : 1
        }
    ],
    "heading" : "Fruits"
}

/* 3 */
{
    "contents" : [ 
        {
            "name" : "Tomatos",
            "count" : 1
        }
    ],
    "heading" : "Vegetables"
}