Mongodb:使字段成为查询中操作的结果

时间:2015-01-26 23:04:56

标签: mongodb mongodb-query aggregation-framework

如何在MongoDB的查询中包含字段操作?

我的文档中包含' start_time'和一个'持续时间'字段,我希望获得所有风​​格活跃的文档(现在'低于' start_time' +' duration')。

PostgreSQL的等价物是:

SELECT * FROM my_table 
    WHERE start_time + (INTERVAL '1 min' * duration)) > current_timestamp

是否可以在MongoDB中使用简单查询,还是应该使用聚合管道来获得相同的结果?

感谢。

1 个答案:

答案 0 :(得分:1)

假设current_timestamp这里是一个外部变量,那么这甚至不是在SQL中表示它的好方法。

正确的方法是做&#34;反向&#34;而不是让数据库重新计算&#34; start_time&#34;值,通过减去持续时间来改变输入值,并使数据库搜索&#34;索引值&#34; &#34;大于&#34; < / strong>正在搜索的时间。

因此,您应该如何使用MongoDB,使用JavaScript示例代替所选语言。很容易理解:

var duration = 5;   // 5 minutes
var current_timestamp = new Date();

var altered_time = new Date( 
    current_timetamp.valueOf() - ( 1000 * 60 * duration )
);

db.collection.find({ "start_time": { "$gt": altered_time } })

实际上,正如SQL表单一样,以这种方式进行比较是实现它的最佳方式。

对于疯狂,或者如果你确实需要比较文档中的两个字段,那么非最佳方法是使用聚合管道,它也不能使用索引来解决它:

db.collection.aggregate([
    { "$project": {
        "doc": "$$ROOT",
        "matched": {
            "$gt": [
                { "$add": [
                    { "$subtract": [ "$start_time", new Date("1970-01-01") ] },
                    1000 * 60 * duration
                ]},
                current_timestamp.valueOf()
            ]
        }
    }},
    { "$match": { "matched": true } }
])

这不是一个好方法,但是你编写的SQL也不是。


因此,持续时间是当前文档中的字段,然后只是以不同的方式进行地址:

db.collection.aggregate([
    { "$project": {
        "doc": "$$ROOT",
        "matched": {
            "$gt": [
                { "$add": [
                    { "$subtract": [ "$start_time", new Date("1970-01-01") ] },
                    { "$multiply": [ 1000 * 60, "$duration" ] }
                ]},
                current_timestamp.valueOf()
            ]
        }
    }},
    { "$match": { "matched": true } }
])