Get data with not,and - mongodb

MongoDB get data with not,and How to get value for INID not equal to 1 and SESSION not equal to 1 ( need to match INID and SESSION in same document ).
Ex:
{
"_id" : ObjectId("5946800b962d74070729407a"),
"INID" : 2,
"SESSION" : 1,
"TD" : ISODate("2017-06-18T13:28:43.409Z"),
"ID" : 2,
"OUT" : [
{
"score" : 50,
"id" : "0",
"out" : {
"status" : "unreachable"
}
}
]
}
{
"_id" : ObjectId("5946800b962d74070729407a"),
"INID" : 3,
"SESSION" : 1,
"TD" : ISODate("2017-06-18T13:28:43.409Z"),
"ID" : 2,
"OUT" : [
{
"score" : 50,
"id" : "0",
"out" : {
"status" : "unreachable"
}
}
]
}
{
"_id" : ObjectId("5946800b962d74070729407a"),
"INID" : 1,
"SESSION" : 1,
"TD" : ISODate("2017-06-18T13:28:43.409Z"),
"ID" : 2,
"OUT" : [
{
"score" : 50,
"id" : "0",
"out" : {
"status" : "unreachable"
}
}
]
}
I want the first two documents.

Well, this worked for me:
db.yourCollectionName.find(
{ $or : [ { INID : {$gt: 1} }, { SESSION : {$gt: 1} } ] }
)
With this query you can have INID larger than 1 or SESSION larger than 1 or both larger than one. Why would you need to negate?
I guess you can also do this:
db.yourCollectionName.find(
{ $or : [ { INID : {$ne: 1} }, { SESSION : {$ne: 1} } ] }
)

Related

Mongo DB update operation

Below query wrongly update by mongoDB
Query:
d.update({'Objects.out.interface': 'down', 'IP': '192.168.106.11', 'INID': 19, 'SESSION': 1, 'Objects.id': 4}, {$set: {'Objects.$.score':888888}})
Why my score 888888 updated in Objects.id:2 not in Objects.id:4 ?
Update result:
{
"_id" : ObjectId("59b7ebec9315080ac2801468"),
"SESSION" : 1,
"INID" : 19,
"IP" : "192.168.106.11",
"Hostname" : "Npppp",
"JOBNAME" : "Nexus2-12-September-19-45-08",
"Authentication" : "{\"username\":\"gowtham\",\"password\":\"pppppp\"}",
"Objects" : [
{
"name" : "self",
"out" : {
"status" : "reachable"
},
"type" : "self_check",
"id" : 1,
"rank" : [
{
"regex" : {
"status" : "down"
},
"score" : 0
},
{
"regex" : {
"status" : "reachable"
},
"score" : 100
}
],
"monitor" : "self",
"score" : 100
},
{
"name" : "Eth1/1",
"out" : {
"interface" : "down"
},
"type" : "cis_sw_int",
"id" : 2,
"rank" : [
{
"regex" : {
"interface" : "down"
},
"score" : 0
},
{
"regex" : {
"interface" : "up"
},
"score" : 100
}
],
"monitor" : "bits,duplex,speed,error",
"score" : 888888
},
{
"name" : "Eth1/37",
"out" : {
"interface" : "down"
},
"type" : "cis_sw_int",
"id" : 3,
"rank" : [
{
"regex" : {
"interface" : "down"
},
"score" : 0
},
{
"regex" : {
"interface" : "up"
},
"score" : 100
}
],
"monitor" : "bits,duplex,speed,error"
},
{
"name" : "Eth1/46",
"out" : {
"interface" : "down"
},
"type" : "cis_sw_int",
"id" : 4,
"rank" : [
{
"regex" : {
"interface" : "down"
},
"score" : 0
},
{
"regex" : {
"interface" : "up"
},
"score" : 100
}
],
"monitor" : "bits,duplex,speed,error"
}
],
"timeout" : 10,
"TD" : ISODate("2017-09-12T19:45:08.743Z")
}
Because you have 2 conditions for subdocuments:
'Objects.out.interface': 'down',
'Objects.id': 4
Positional operator uses first matching sub-document
the positional $ operator acts as a placeholder for the first element that matches the query document,
In your case the first match for 'Objects.out.interface': 'down' is the one with id:2.
You need to change the filter to use $elemMatch to use both conditions to identify the subdocument:
{
'IP': '192.168.106.11',
'INID': 19,
'SESSION': 1,
'Objects': {
$elemMatch: {
'out.interface': 'down',
'id': 4
}
}
}

How to sort nested object

db.sort.drop();
db.sort.insert({stats: [{userId: 1, date: '01012013'},{userId: 2, date: '31122012'}]});
db.sort.insert({stats: [{userId: 1, date: '31122013'},{userId: 2, date: '01012012'}]});
> db.sort.find({'stats.userId': 1}).sort({'stats.date': 1}).pretty()
{
"_id" : ObjectId("52af1ce974be7dbd071e8563"),
"stats" : [
{
"userId" : 1,
"date" : "31122013"
},
{
"userId" : 2,
"date" : "01012012"
}
]
}
{
"_id" : ObjectId("52af1ce974be7dbd071e8562"),
"stats" : [
{
"userId" : 1,
"date" : "01012013"
},
{
"userId" : 2,
"date" : "31122012"
}
]
}
How to get the documents sorted by date userId: 1?
I expect to see:
{
"_id" : ObjectId("52af1ce974be7dbd071e8562"),
"stats" : [
{
"userId" : 1,
"date" : "01012013"
},
{
"userId" : 2,
"date" : "31122012"
}
]
}
{
"_id" : ObjectId("52af1ce974be7dbd071e8563"),
"stats" : [
{
"userId" : 1,
"date" : "31122013"
},
{
"userId" : 2,
"date" : "01012012"
}
]
}
Something along the lines of:
db.COLLECTION.find({stats.userID: 1}).sort({'stats.date':1})
Given your data above, when I execute that query, I get this back:
"stats" : [
{
"userId" : 1,
"date" : 1012013
}
You could use the aggregation framework to achieve
db.sort.aggregate(
[
{$unwind:"$stats"},
{$match:{"stats.userId":1}},
{$sort:{"stats.date":1}}
]);
If you could change your schema to store the user+id combination as the field name with the date as its value then you accomplish this easily
> db.so2.find().pretty()
{
"_id" : 1,
"stats" : [
{
"userId1" : "01012013"
},
{
"userId2" : "31122012"
}
]
}
{
"_id" : 2,
"stats" : [
{
"userId1" : "31122013"
},
{
"userId2" : "01012012"
}
]
}
You then change the query predicate from userId : 1 to check for existence of the userId field
> db.so2.find({"stats.userId1":{$exists:1}}).sort({"stats.userId1":1}).pretty()
{
"_id" : 1,
"stats" : [
{
"userId1" : "01012013"
},
{
"userId2" : "31122012"
}
]
}
{
"_id" : 2,
"stats" : [
{
"userId1" : "31122013"
},
{
"userId2" : "01012012"
}
]
}

mongo shell: return only 1 element of nested array

I have the following data on a mongodb:
{
"name" : "bla",
"log" : [
{
"A" : 1,
"B" : 10
},
{
"A" : 2,
"B" : 20
}
]
}
I understand how to return all values of A from the mongoshell:
db.test.find({},{'name':1,'log.A':1})
{ "_id" : ObjectId("52712539c99a2fc6f6088cd4"), "name" : "bla", "log" : [ { "A" : 1 }, { "A" : 2 } ] }
but how can I limit the output of A to only the first element? This is the output that I extect to have:
{ "_id" : ObjectId("52712539c99a2fc6f6088cd4"), "name" : "bla", "log.A" : 1, "log.B":10}
I don't mind in having log.A or just A, or even having some [ ] in the output, as soon as it is always only one entry for A and for B
how can I do it?
You can use the $slice array projection operator to do that:
db.test.find({}, {name: 1, 'log.A':1, log: {$slice: 1}})
Outputs:
{ "_id" : ObjectId("..."), "name" : "bla", "log" : [ { "A" : 1 } ] }

MongoDB groupby query

I have colletions containing records like
{ "type" : "me", "tid" : "1" }
{ "type" : "me", "tid" : "1" }
{ "type" : "me", "tid" : "1" }
{ "type" : "you", "tid" : "1" }
{ "type" : "you", "tid" : "1" }
{ "type" : "me", "tid" : "2" }
{ "type" : "me", "tid" : "2"}
{ "type" : "you", "tid" : "2"}
{ "type" : "you", "tid" : "2" }
{ "type" : "you", "tid" : "2"}
I have want result like below
[
{"tid" : "1","me" : 3,"you": 2},
{"tid" : "2","me" : 2,"you": 3}
]
I have tried group and; aggregate queries doesn't get required result format.
below is the group query.
db.coll.group({
key: {tid : 1,type:1},
cond: { tid : { "$in" : [ "1","2"]} },
reduce: function (curr,result) {
result.total = result.total + 1
},
initial: { total : 0}
})
it result is like
[
{"tid" : "1", "type" : "me" ,"total": 3 },
{"tid" : "1","type" : "you" ,"total": 2 },
{"tid" : "2", "type" : "me" ,"total": 2 },
{"tid" : "2","type" : "you" ,"total": 3 }
]
following is aggregate query
db.coll.aggregate([
{$match : { "tid" : {"$in" : ["1","2"]}}},
{$group : { _id : {tid : "$tid",type : "$type"},total : {"$sum" : 1}}}
])
gives following result
{
"result" :
[
{"_id" : {"tid" : "1","type" : "me"},"total" : 3},
{"_id" : {"tid" : "2","type" : "me" },"total" : 2},
{"_id" : {"tid" : "2","type" : "you"},"total" : 3}
]
"ok" : 1
}
it is possible to obtain I specified result or I have to do some manipulation in my code.
Thanks
If you change your aggregation to this:
db.so.aggregate([
{ $match : { "tid" : { "$in" : ["1", "2"] } } },
{ $group : {
_id : { tid : "$tid", type : "$type" },
total : { "$sum" : 1 }
} },
{ $group : {
_id : "$_id.tid",
values: { $push: { type: "$_id.type", total: '$total' } }
} }
])
Then your output is:
{
"result" : [
{
"_id" : "1",
"values" : [
{ "type" : "you", "total" : 2 },
{ "type" : "me", "total" : 3 }
]
},
{
"_id" : "2",
"values" : [
{ "type" : "me", "total" : 2 },
{ "type" : "you", "total" : 3 }
]
}
],
"ok" : 1
}
Although that is not the same as what you want, it is going to be the closest that you can get. And in your application, you can easily pull out the values in the same was as with what you would like to get out of it.
Just keep in mind, that in general you can not promote a value (you, me) to a key — unless your key is of a limited set (3-4 items max).

MongoDB Update $push Cannot apply the positional operator without a corresponding query field containing an array

model:
{
"_id" : "a62107e10f388c90a3eb2d7634357c8b",
"_appid" : [
{
"_id" : "1815aaa7f581c838",
"events" : [
{
"_id" : "_TB_launch",
"boday" : [
{
"VERSIONSCODE" : "17",
"NETWORK" : "cmwap",
"VERSIONSNAME" : "2.4.0",
"IMSI" : "460026319223205",
"PACKAGENAME" : "com.androidbox.astjxmjmmshareMM",
"CHANNELID" : "xmjmm17",
"CHANNELNAME" : "浠..?.M寰.俊?.韩?.?1.x锛.,
"eventid" : "_TB_launch",
"uuid" : "a62107e10f388c90a3eb2d7634357c8b",
"creattime" : "1366300799766",
"ts" : ISODate("2013-04-25T06:28:36.403Z")
}
],
"size" : 1
}
],
"size" : 1
}
],
"size" : 1
}
> db.events.update(
{
"_id":"039e569770cec5ff3811e7410233ed27",
"_appid._id":"e880db04064b03bc534575c7f831a83a",
"_appid.events._id":"_TB_launch"
},
{
"$push":{
"_appid.$.events.$.boday":{"111":"123123"}
}
}
);
Cannot apply the positional operator without a corresponding query field containing an array.
Why?!!
You are trying to reference multiple levels of embedding - you can only have one positional $ operator. You won't be able to do something like this until this feature request has been implemented.
Response Here
The short answer is, "no", but working with nested arrays gets
tricky. Here is an example:
db.foo.save({_id: 1, a1:[{_a1id:1, a2:[{a2id:1, a3:[{a3id:1, a4:"data"}]}]}]})
db.foo.find()
{ "_id" : 1, "a1" : [
{ "_a1id" : 1, "a2" : [
{ "a2id" : 1, "a3" : [
{ "a3id" : 1, "a4" : "data" }
] }
] }
] }
db.foo.update({_id:1}, {$push:{"a1.0.a2.0.a3":{a3id:2, a4:"other data"}}})
db.foo.find()
{ "_id" : 1, "a1" : [
{ "_a1id" : 1, "a2" : [
{ "a2id" : 1, "a3" : [
{ "a3id" : 1, "a4" : "data" },
{ "a3id" : 2, "a4" : "other data" }
] }
] }
] }
If you are unsure where one of your sub-documents lies within an
array, you may use one positional operator, and Mongo will update the
first sub-document which matches. For example:
db.foo.update({_id:1, "a1.a2.a2id":1}, {$push:{"a1.0.a2.$.a3":{a3id:2, a4:"other data"}}})