2013-09-14 2 views
0

Вот структура часть моей коллекции:Mongo_count для поддокументов в MongoDB драйвере C

{ 
    ... 
    list: [ 
     { id:'00A', name:'None 1' }, 
     { id:'00B', name:'None 2' }, 
    ], 
    ... 
} 

После использования функции «отчетливая» (ссылка: sub-object in sub-array in mongodb-C)

Что бы лучшее решение для меня, чтобы подсчитать количество поддокументов, пожалуйста?

Поскольку использование mongo_count несовместимо с отдельной функцией mongo_run_command().

+0

Вы не можете получить длина/размер массива в MongoDB непосредственно. Наиболее распространенная рекомендация - хранить его отдельно. – WiredPrairie

+0

Я не хочу получать размер массива, но хочу подсчитать количество элементов в массиве «список». В результате в моем примере было бы 2. –

+0

Как 'count' отличается от' length'/'size'? Я бы сказал, что «длина» - «2». У MongoDB нет эффективного способа вернуть 'count/length/size' массива. – WiredPrairie

ответ

1

Было бы полезно, если бы вы включили дополнительную информацию в свой вопрос, например, какую версию вы используете и какова ваша общая цель. Монго - особый случай. Я понимаю, что вы хотите получить количество элементов в массиве. Когда задействованы массивы, структура агрегации [AF] часто является самым простым способом для выполнения вашей задачи (к сожалению, в это время вам также может понадобиться использовать уменьшение карты для более сложных запросов). Вы должны изменить приведенный ниже пример для своего конкретного случая. Этот пример работает с драйвером C 0.8 и mongodb 2.4.6. Существует один массивный оговорка на Mongo, отличающийся от SQL за пределами использования отдельных. Поддокументы сравниваются в двоичном представлении (пример ниже). Таким образом, значение отдельных в Mongo немного отличается от термина SQL для поддокументов. Поэтому {..., subdoc: [{a: 1, b: 1}]} {..., subdoc: [{b: 1, a: 1}]} представляют два различных значения поддоку. Это относится только к поддокументам; поля верхнего уровня могут быть в любом порядке. Кроме того, Mongo не гарантирует порядок полей в документе, кроме массивов. Таким образом, пока агрегация на subdoc.a будет гарантировать полученные вами результаты (при условии, что сам сам по себе не является поддокументом), агрегация на subdoc не будет.

Если вы хотите сравнить поле subdoc с помощью карты поля, можно использовать сокращение. Уменьшение карты сложности на несколько порядков выше AF. В случае, если вы хотите прочитать о MapReduce: http://docs.mongodb.org/manual/core/map-reduce/

Теперь, когда мы получили через все disclamers и предупреждения: командная оболочка AF ниже будет рассчитывать все правильно с тем же идентификатором: db.collection.aggregate ({ $ relind: "$ list"}, {$ group: {_id: "$ list.id", count: {$ sum: 1}}}) Эта команда суммирует количество отдельных документов в коллекции по списку. К сожалению, драйвер C не имеет вспомогательной команды агрегации. Функция mongo_run_command должна использоваться для запуска агрегации. Имейте в виду, что это может вернуть только документ bson, а не курсор; поэтому результаты ограничены пределом размера документа (Mongo 2.5.3, 16Megs). Две примеры примеров C на субдоке в целом для целей равенства, поэтому для этих вопросов упорядочения. Вам нужно добавить . , чтобы получить конкретное поле (которое снова не может быть subdoc или у вас будут те же ограничения, о которых уже говорилось).

Вот пример использования ОСБК (http://api.mongodb.org/c/current/bcon.html), рекомендуемый метод для легкого использования (это ~ 10% медленнее, чем, например, два):

#include <mongo.h> 
#include <bcon.h> 
#include <stdio.h> 

int main() { 
    /* 
    * We assume objects in the form of {_id:<any_id>, list:[{a:<int>,b:<int>}, ...]} 
    */ 
    char table[] = "agg"; 
    mongo conn[1]; 
    mongo_init(conn); 
    if(MONGO_OK != mongo_client(conn, "127.0.0.1", 27017)) 
     return 1; 
    bson b[1], b_result[1]; 

    /*create the aggregation command in bson*/ 
    bcon cmd_aggregate[] = { "aggregate", BRS(table), 
      "pipeline", 
      "[", 
       "{", 
        "$unwind", "$list", 
       "}", 
       "{", 
        "$group", 
        "{", 
         "_id", "$list", 
         "distinct_count", 
         "{", 
          "$sum", BI(1), 
         "}", 
        "}", 
       "}", 
      "]", 
      BEND 
    }; 
    bson_from_bcon(b, cmd_aggregate); 

    /*So you can see your command*/ 
    bson_print(b); 

    /*run the command*/ 
    mongo_run_command(conn, "test", b, b_result); 

    /*command results*/ 
    bson_print(b_result); 

    bson_destroy(b_result); 
    bson_destroy(b); 
    mongo_destroy(conn); 
    return 0; 
} 

Вот является немного быстрее стиль:

#include <mongo.h> 
#include <stdio.h> 

int main() { 
    /* 
    * We assume objects in the form of {_id:<any_id>, list:[{a:<int>,b:<int>}, ...]} 
    */ 
    char table[] = "agg"; 
    mongo conn[1]; 
    mongo_init(conn); 
    if(MONGO_OK != mongo_client(conn, "127.0.0.1", 27017)) 
     return 1; 
    bson b[1], b_result[1]; 
    /*create the aggregation command in bson*/ 
    bson_init(b); 
     bson_append_string(b, "aggregate", "agg"); 
     bson_append_start_array(b, "pipeline"); 
      bson_append_start_object(b,"0"); 
       bson_append_string(b, "$unwind", "$list"); 
      bson_append_finish_object(b); 
      bson_append_start_object(b,"1"); 
       bson_append_start_object(b,"$group"); 
        bson_append_string(b,"_id", "$list"); 
        bson_append_start_object(b, "_count"); 
         bson_append_int(b, "$sum", 1); 
        bson_append_finish_object(b); 
       bson_append_finish_object(b); 
      bson_append_finish_object(b); 
     bson_append_finish_array(b); 
     bson_finish(b); 

    /*So you can see your command*/ 
    bson_print(b); 

    /*run the command*/ 
    mongo_run_command(conn, "test", b, b_result); 

    /*command results*/ 
    bson_print(b_result); 

    bson_destroy(b_result); 
    bson_destroy(b); 
    mongo_destroy(conn); 
    return 0; 
} 

Последнее, но не менее важное: подключение базы данных в оболочке, а затем запуск следующих команд позволит вам увидеть запросы (если вы запустили базу данных непосредственно из командной строки и не разблокировали ее, вы можете увидеть их в этот терминал):

use admin 
db.runCommand({ setParameter: 1, logLevel: 1 }) 

Это полезно для отладки команды, которую вы считаете отправкой в ​​базу данных. В этом терминале он должен выглядеть так же, как и в оболочке mongo.

Надеюсь, это охватывает все аспекты вашего вопроса. Позвольте мне знать, если вам нужно что-нибудь еще.

Best, Charlie

+0

Благодарим вас за ответ. Это очень помогло мне понять, как работает драйвер MongoDB C! Я, наконец, решил выбрать другой способ подсчета количества поддокументов! Вы также можете получить дополнительную информацию о цели моего вопроса в этом посте: http://stackoverflow.com/questions/18838067/use-of-mongodb-c-driver –

Смежные вопросы