MongoDB выбирает все, где значение поля в списке запросов

Как добиться ниже SQL в MongoShell?

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

Сбор пользовательского трафика

{
    "_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
        })

Здесь я считаю, что это делает равно сравнению, но я хочу, чтобы это делало как сравнение %%

Как только я получу результат, я хочу обновить этот набор результатов как 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
        })
    }

person HaBo    schedule 17.03.2014    source источник


Ответы (2)


Ни в одном запросе это не так.

Нет ничего плохого в том, чтобы получить результаты запроса и передать их как ваше состояние.

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

results = db.collectionB.find({ "newfield": { "$in": list } });

Но ваша истинная цель не ясна, так как использование только SQL-запросов в качестве единственного примера того, чего вы хотите достичь, обычно не является хорошим руководством для ответа на вопрос. Основная причина этого заключается в том, что вы, вероятно, должны моделировать иначе, чем в реляционном моделировании. Иначе зачем вообще использовать MongoDB?

Я бы посоветовал прочитать раздел документации по моделированию данных, в котором показано несколько примеров подхода к распространенным случаям моделирования.

Учитывая эту информацию, то, возможно, вы сможете пересмотреть то, что вы моделируете, и если у вас потом возникнут конкретные вопросы к другим проблемам там, то не стесняйтесь задавать свои вопросы здесь.

person Neil Lunn    schedule 17.03.2014
comment
Как добиться того же с помощью аналогичного оператора newfield: {$like: list} - person HaBo; 17.03.2014
comment
Расширил мой вопрос, посмотрите, имеет ли это смысл в моделировании Mongo - person HaBo; 17.03.2014

Наконец, вот как я мог это сделать.

// 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
                            })
                    } 
                  });
            }
        });
person HaBo    schedule 18.03.2014