mongodb c ++驱动程序没有upsert

时间:2014-08-05 22:29:35

标签: c++ mongodb upsert

在mongodb,我有这个文档:

{
"_id" : ObjectId("53e157918b3354f7157142d2"),
"packet" : [ 
    {
        "datetime" : ISODate("2014-08-05T16:16:46.337Z"),
        "signallingType" : "M2PA",
        "clgNum" : "",
        "cldNum" : "",
        "opc" : "6406",
        "dpc" : "327",
        "transState" : "continue",
        "otid" : "M2PA042f2ee0",
        "dtid" : "",
        "sccpCalling" : "523331461111",
        "sccpCalled" : "52333033342222",
        "imsi" : "",
        "operation" : "sendAuthenticationInfo (56)",
        "camelClgNum" : "",
        "camelCldNum" : "",
        "camelCallRefNum" : "",
        "camelImsi" : "",
        "camelEvent" : "",
        "camelReleaseCause" : "",
        "pcapFileName" : "/home/monitor/tmp/gsm_eth2_06700_20140805165712.pcap",
        "message" : "dddvid"
    }
]

}

如果我从shell执行以下操作:

db.packets.update( 
{ $and: [ 
    { $or: [ 
        { "packet.otid": { $in: [ "M2PA042f2ee0" ] } },
        { "packet.dtid": { $in: [ "M2PA042f2ee0" ] } }
    ] },
    { $or: [
        { "packet.sccpCalling": { $in: [ "523331461111", "52333033342222" ] } },
        { "packet.sccpCalled": { $in: [ "523331461111", "52333033342222" ] } }
    ] }
] }, 
{ $push: { packet: { datetime: new Date(1407255406337) } } }, true 
)

该文档没有问题。 现在,用c ++我做:

class Packet {

public:
    std::string packetDate;
    std::string signallingType;
    int creationTimeStamp;
    std::string clgNum;
    std::string cldNum;
    std::string opc;
    std::string dpc;
    std::string transState;
    std::string otid;
    std::string dtid;
    std::string message;
    std::string sccpCalling;
    std::string sccpCalled;
    std::string imsi;
    std::string operation;
    std::string camelClgNum;
    std::string camelCldNum;
    std::string camelCallRefNum;
    std::string camelImsi;
    std::string camelEvent;
    std::string camelReleaseCause;
    std::string pcapFile;
...

我被要求展示我如何创建" query_otid_or"和query_sccp_or":

mongo::BSONObj query;
mongo::BSONObj objError;
mongo::BSONObj query_otid;
mongo::BSONObj query_dtid;
mongo::BSONObj query_sccpCalling;
mongo::BSONObj query_sccpCalled;
mongo::BSONObj query_otid_or;
mongo::BSONObj query_sccp_or;
...
        tcapValuesArray.clear(); sccpValuesArray.clear();
        if( (it)->otid.length() > 0 ){
            tcapValuesArray.push_back( (it)->otid );
        }

        if( (it)->dtid.length() > 0 ){
            tcapValuesArray.push_back( (it)->dtid );
        }

        if( (it)->sccpCalling.length() > 0 ){
            sccpValuesArray.push_back( (it)->sccpCalling );
        }
        if( (it)->sccpCalled.length() > 0 ){
            sccpValuesArray.push_back( (it)->sccpCalled );
        }

        query_otid = BSON( "\"packet.otid\"" <<  BSON( "$in" << tcapValuesArray ) );
        query_dtid = BSON( "\"packet.dtid\"" <<  BSON( "$in" << tcapValuesArray ) );

        query_sccpCalling = BSON( "\"packet.sccpCalling\"" << BSON( "$in" << sccpValuesArray ) );
        query_sccpCalled = BSON( "\"packet.sccpCalled\"" << BSON( "$in" << sccpValuesArray ) );

        query_otid_or = mongo::OR( query_otid, query_dtid );
        query_sccp_or = mongo::OR( query_sccpCalling, query_sccpCalled );

...

c.update("tracer.packets",
  BSON( "$and" << BSON_ARRAY( query_otid_or << query_sccp_or ) ),
  BSON( "$push" << BSON("packet" << BSON( "datetime" << mongo::Date_t( atoll( ((it)->packetDate.substr(0,10) + (it)->packetDate.substr(11,3)).c_str() ))))), 
  true, 
  true);

它不起作用,插入一条新记录......虽然它是完全相同的命令......

有人有任何想法吗?

1 个答案:

答案 0 :(得分:1)

要清楚,在第一个示例中(通过shell)运行upsert的结果是文档在查询匹配时会更新。

对我来说似乎工作得很好,我认为你已经过时了"\"packet.sccpCalling\"""\"packet.sccpCalled\""

#include <iostream>
#include <vector>
#include <cassert>
#include "mongo/client/dbclient.h"

using namespace std;
using namespace mongo;

int main() {
    client::initialize();

    DBClientConnection conn;
    conn.connect("localhost");
    conn.dropDatabase("test");

    BSONObjBuilder bob;
    BSONArrayBuilder bab;
    BSONObjBuilder packet;

    packet.append("otid", "M2PA042f2ee0");
    packet.append("sccpCalling", "523331461111");
    packet.append("sccpCalled", "52333033342222");

    bab.append(packet.obj());
    bob.appendArray("packet", bab.obj());
    conn.insert("test.test", bob.obj());

    vector<std::string> tcapValuesArray;
    tcapValuesArray.push_back("M2PA042f2ee0");
    vector<std::string> sccpValuesArray;
    sccpValuesArray.push_back("523331461111");
    sccpValuesArray.push_back("52333033342222");

    BSONObj query_otid = BSON( "packet.otid" <<  BSON( "$in" << tcapValuesArray ) );
    BSONObj query_sccpCalling = BSON( "packet.sccpCalling" << BSON( "$in" << sccpValuesArray ) );
    BSONObj query_sccpCalled = BSON( "packet.sccpCalled" << BSON( "$in" << sccpValuesArray ) );

    BSONObj query_otid_or = OR( query_otid, query_otid );
    BSONObj query_sccp_or = OR( query_sccpCalling, query_sccpCalled );

    BSONObj query = BSON( "$and" << BSON_ARRAY( query_otid_or << query_sccp_or ) );
    BSONObj update = BSON( "$push" << BSON("packet" << BSON( "datetime" << "updated")));

    cout << "this is the query: " << query.toString() << endl;
    conn.update("test.test", query, update, true, true);

    assert( 1 == conn.count("test.test"));
    assert( 1 == conn.count("test.test", Query("{ 'packet.datetime': 'updated' }")));
}
相关问题