Многократен $group в структуре скопления MongoDB в MongoDB 2.2, пронизывал?

Я задаюсь вопросом, многократна ли функция $group в структуре скопления MongoDB 2.2, пронизывал.

Для этого вопроса я сделал некоторые маленькие тесты. Набор данных, который я использовал, используется, чтобы сохранить приблизительно 4 миллиона электронных писем, и у каждой электронной почты есть формат как указано ниже:

shard1:PRIMARY> db.spams.findOne()
{
"IP" : "113.162.134.245",
"_id" : ObjectId("4ebe8c84466e8b1a56000028"),
"attach" : [ ],
"bot" : "Lethic",
"charset" : "iso-8859-1",
"city" : "",
"classA" : "113",
"classB" : "113.162",
"classC" : "113.162.134",
"content_type" : [ ],
"country" : "Vietnam",
"cte" : "7bit",
"date" : ISODate("2011-11-11T00:07:12Z"),
"day" : "2011-11-11",
"from_domain_a" : "domain157939.com",
"geo" : "VN",
"host" : "",
"lang" : "unknown",
"lat" : 16,
"long" : 106,
"sequenceID" : "user648",
"size" : 1060,
"smtp-mail-from_a" : "[email protected]",
"smtp-rcpt-to_a" : "[email protected]",
"subject_ta" : "nxsy8",
"uri" : [ ],
"uri_domain" : [ ],
"x_p0f_detail" : "2000 SP4, XP SP1+",
"x_p0f_genre" : "Windows",
"x_p0f_signature" : "65535:105:1:48:M1402,N,N,S:."
}

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

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

public class RangeQuery {
final private String mongoUrl = "172.16.10.61:30000";
final private String databaseName = "test";
final private String collecName = "spams";
private DBCollection collection = null;
private DB db = null;

    public void init(){
    Mongo mongo = null;
    try {
        mongo = new Mongo(new DBAddress(mongoUrl));
    } catch (MongoException e) {
       //TODO Auto-generated catch block
        e.printStackTrace();
    } catch (UnknownHostException e) {
       //TODO Auto-generated catch block
        e.printStackTrace();
    }
    db = mongo.getDB(databaseName);
    db.requestStart();
    collection = db.getCollection(collecName);
}

    public void queryRange_GroupBot(boolean printResult){
    DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss'Z'");
    String toDateStr [] = new String[5] ;
    toDateStr[0] = "2011-01-02T00:00:00Z";
    toDateStr[1] = "2011-01-07T00:00:00Z";
    toDateStr[2] = "2011-02-01T00:00:00Z";
    toDateStr[3] = "2011-06-01T00:00:00Z";
    toDateStr[4] = "2012-01-01T00:00:00Z";

    String toPrint [] = new String[5];
    toPrint[0] = "Within One day";
    toPrint[1] = "Within One week";
    toPrint[2] = "Within One month";
    toPrint[3] = "Within half year";
    toPrint[4] = "Within One year";

    try {
        System.out.println("\n------Query Time Range Group by Bot------");
        for(int i = 0;i < 5;i++){
            System.out.println("    ---" + toPrint[i] + "---");
            Date fromDate = formatter.parse("2011-01-01T00:00:00Z");
            Date toDate = formatter.parse(toDateStr[i]);

            DBObject groupFields = new BasicDBObject( "_id", "$bot");
            groupFields.put("sum", new BasicDBObject( "$sum", 1));
            DBObject group = new BasicDBObject("$group", groupFields);

            DBObject cond1 = new BasicDBObject();
            cond1.put("date", new BasicDBObject("$gte", fromDate));
            DBObject cond2 = new BasicDBObject();
            cond2.put("date", new BasicDBObject("$lte", toDate));
            DBObject match1 = new BasicDBObject("$match", cond1 );
            DBObject match2 = new BasicDBObject("$match", cond2 );

            for(int j = 0;j < 1;j++){
                Long runBefore = Calendar.getInstance().getTime().getTime();
                AggregationOutput aggOutput = collection.aggregate(match1, match2, group);
                Long runAfter = Calendar.getInstance().getTime().getTime();
                if(printResult){
                    System.out.println(aggOutput.getCommandResult());
                }
                System.out.println("[Query Range + Group by Bot]: " + (runAfter - runBefore) + " ms.");
            }
        }
    } catch (ParseException e) {
       //TODO Auto-generated catch block
        e.printStackTrace();
    }
}

    public static void main(String[] args){
    RangeQuery rangQuery = new RangeQuery();
    rangQuery.init();
    rangQuery.queryRange_GroupBot_MapReduce(true);
  }
  }

Результат смотрит как это:

  Within One day(2011-01-01 -> 2011-01-02)      54173 ms
  Within One week(2011-01-01 -> 2011-01-07)     54277 ms
  Within One month(2011-01-01 -> 2011-02-01)    54387 ms
  Within half year(2011-01-01 -> 2011-06-01)    53035 ms
  Within One year(2011-01-01 -> 2012-01-01)     54116 ms

То, что удивляет меня, - то, что обычно группа, более чем один год должен быть медленнее, чем один день, так как это содержит больше отчетов. (отчеты в наборе данных однородны распределенный со временем),

Если я просто использую db.spams.find ({"дата": {$gt:ISODate (xxx), {$lt: xxx } }}) .count, я вижу, что сомнение года стоит дольше, чем сомнение дня.

Но почему, когда я использую $group, эта функция занимает почти то же самое время, когда я увеличиваю диапазон времени?

Я знаю, что структура скопления находится в C++, я использую mongodb 2.2, структура скопления использовали многократные нити или некоторые другие методы, чтобы улучшить работу?

0
nl ja de

1 ответы

According to this discussion: https://groups.google.com/forum/?fromgroups=#!topic/mongodb-user/xCSww5spXPc

Каждый трубопровод в настоящее время единственный, пронизывал, но можно бежать отличающийся трубопроводы параллельно. Таким образом, если у вас будет 100 связей каждое управление командой скопления, те будут потенциально бежать параллельно - но каждая команда будет работать на 1 нити.

1
добавлено
Я мог предположить только, что, в то время как у вас нет индексов, (если не) две фазы матча так или иначе должны просмотреть данные (по крайней мере, первое, неважно какой длины интервал), и последний шаг, группировка находится в памяти.
добавлено автор attish, источник
в этом случае: docs.mongodb.org/manual/applications/aggregation/… группа будет управлять paralelly на черепках, mongos объединит результат, и матч только исключит черепки. Именно поэтому нет никаких действительно больших различий просто, комбинация работает на mongos
добавлено автор attish, источник
Спасибо, если один трубопровод одно-переплетен, почему время для группировки одного года может совпасть с группировкой однажды? Хотя MongoDB управляет им в памяти, я думаю, что это не может бежать настолько быстро как это...
добавлено автор Felix, источник
Привет attish, на самом деле я действительно добавлял индекс, чтобы "датироваться", который является областью, на которой я подвергаю сомнению. Я запустил этот тест на окружающей среде черепка и использование "дата" как sharding-ключ. Поскольку вы знаете, что мы должны внести его в указатель перед использованием его как sharding-ключ.
добавлено автор Felix, источник
DBA - русскоговорящее сообщество
DBA - русскоговорящее сообщество
1 345 участник(ов)

Общаемся и обсуждаем темы, посвященные DBA, PostgreSQL, Redis, MongoDB, MySQL, neo4j, riak и т.д. См. также: @devops_ru, @kubernetes_ru, @docker_ru, @nodejs_ru Рекомендуем сразу отключить уведомления, чтобы пребывание здесь было полезным и комфортным.

MongoDB Russian
MongoDB Russian
1 086 участник(ов)

> db.stats() https://combot.org/chat/-1001035023078