【问题标题】:MongoDB select all where field value in a query listMongoDB选择查询列表中的所有where字段值
【发布时间】:2014-03-17 03:36:16
【问题描述】:

如何在MongoShell中实现以下SQL?

Select TableA.* from TableA where TableA.FieldB in (select TableB.FieldValue from TableB)

Mongo doc 给出了一些

的例子
db.inventory.find( { qty: { $in: [ 5, 15 ] } } )

我希望该数组动态来自另一个查询。有可能吗?

扩展我的问题

我有一组bot 名字

机器人集合

{
    "_id" : ObjectId("53266697c294991f57c36e42"),
    "name" : "teoma"
}

我有一个用户流量的集合,在那个流量集合中,我有一个字段useragent

userTraffic 集合

{
    "_id" : ObjectId("5325ee6efb91c0161cbe7b2c"),
    "hosttype" : "http",
    "useragent" : "Mediapartners-Google",
    "is_crawler" : false,
    "City" : "Mountain View",
    "State" : "CA",
    "Country" : "United States"
}

我想选择其useragent 包含bot 集合的任何名称的所有用户流量文档

这是我想出来的

var botArray = db.bots.find({},{name:1, _id:0}).toArray()

db.Sessions.find({
    useragent: {$in: botArray}
    },{ 
        ipaddress:1
        })

这里我相信它在做 equals to comparison,但我希望它做 like %% comparison

获得结果后,我想将该结果集更新为 is_crawler=true

试过这样的方法,没用

db.bots.find().forEach( function(myBot) {
    db.Sessions.find({
        useragent: /myBot.name/
        },{ 
            ipaddress:1
            }) 
     });

另一种循环记录的方式,但没有找到匹配项。

var bots = db.bots.find( {
    $query: {}, 
    $orderby:{
        name:1}
        });
while( bots.hasNext()) {
    var bot = bots.next();
    //print(bot.name);
    var botName = bot.name.toLowerCase();
    print(botName);
     db.Sessions.find({
        useragent: /botName/,
        is_crawler:false
        },{ 
            start_date:1,
            ipaddress:1,
            useragent:1,
            City:1,
            State:1,
            Country:1,
            is_crawler:1,
            _id:0
        })
    }

【问题讨论】:

    标签: mongodb mongodb-.net-driver mongo-shell


    【解决方案1】:

    不是在单个查询中。

    从查询中获取结果并将其作为您的条件输入并没有错。

    var list = db.collectionA.find({},{ "_id": 0, "field": 1 }).toArray();
    
    results = db.collectionB.find({ "newfield": { "$in": list } });
    

    但您的实际目的并不清楚,因为单独使用 SQL 查询作为您想要实现的唯一示例通常不是回答问题的好指南。造成这种情况的主要原因是您可能应该进行建模而不是关系建模。否则,为什么要使用 MongoDB?

    我建议阅读Data Modelling 上的文档部分,其中展示了如何处理常见建模案例的几个示例。

    考虑到这些信息,也许您可​​以重新考虑您正在建模的内容,如果您对那里的其他问题有具体问题,请随时在此处提出您的问题。

    【讨论】:

    • 如何实现与like语句相同的“newfield”:{“$like”:list}
    • 扩展了我的问题,看看这在 Mongo Modeling 中是否有意义
    【解决方案2】:

    我终于可以做到了。

    // Get a array with values for name field
    var botArray = db.bots.find({},{name:1}).toArray();
    
    // loop through another collection
            db.Sessions.find().forEach(function(sess){
                if(sess.is_crawler == false){ // check a condition
                     // loop in the above  array
                    botArray.forEach(function(b){
                    //check if exists in the array
                       if(String(sess.useragent).toUpperCase().indexOf(b.name.toUpperCase()) > -1){
                            db.Sessions.update({ _id : sess._id} // find by _id
                            ,{
                                is_crawler : true // set a update value
                                },
                                {
                                    upsert:false // do update only
                                })
                        } 
                      });
                }
            });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-06
      • 2018-06-30
      • 2014-12-15
      • 1970-01-01
      • 2010-09-13
      • 2013-08-29
      • 2019-09-25
      • 1970-01-01
      相关资源
      最近更新 更多