在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);
它不起作用,插入一条新记录......虽然它是完全相同的命令......
有人有任何想法吗?
答案 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' }")));
}