java mongodb 3.0: find value in internal array of documents -


i'm using java , mongodb v.3.0.7. have list of player internal array of games scores. test insert document:

public void insertplayer(string id_device) throws parseexception{     dateformat format = new simpledateformat("yyyy-mm-dd't'hh:mm:ss'z'", locale.english);     db.getcollection("player").insertone(                     new document()                             .append("nikname", "guest")                             .append("password", "guest")                             .append("my_id", "")                             .append("id_device", id_device)                             .append("language", "italian")                             .append("games", aslist(                             new document()                                     .append("gamename", "ppa")                                     .append("banned", false)                                     .append("date", format.parse("2014-10-01t00:00:00z"))                                     .append("score", 11),                             new document()                                     .append("gamename", "test2game")                                     .append("banned", false)                                     .append("date", format.parse("2014-01-16t00:00:00z"))                                     .append("score", 17)))             ); } 

to find if player banned particular game i'm doiing this:

public boolean isbanned(string id_device){     finditerable<document> iterable = db.getcollection("player").find(eq("id_device", "machine1"));      system.out.println(iterable.first());     list<document> dl = (list<document>)iterable.first().get("games");     for(int i=0;i<dl.size();i++){         document d = dl.get(i);         system.out.println(d.getstring("gamename"));         if(d.getstring("gamename").equals("ppa")){             boolean ban = d.getboolean("banned");             return ban;         }     } 

there faster way using embedded mongodb methods find document:

new document() .append("gamename", "ppa") .append("banned", false) .append("date", format.parse("2014-10-01t00:00:00z")) .append("score", 11), 

giving id_device , gamename? thanks

to achieve that, need aggregate data. https://docs.mongodb.org/manual/aggregation/

depending on usecase, aggregation may change (more query, more pipeline steps).

here data:

{     "_id" : objectid("569a30a30586bcb40f7d2531"),     "my_id" : "",     "id_device" : "machine1",     "language" : "italian",     "games" : [          {             "gamename" : "ppa",             "banned" : true,             "date" : isodate("2014-10-01t00:00:00.000z"),             "score" : 11         },          {             "gamename" : "test2game",             "banned" : false,             "date" : isodate("2014-01-16t00:00:00.000z"),             "score" : 17         }     ] } 

i assume:

you have list of unique players. each of them play unique games. (example: player1 never plays ppa twice)  so, need search game player banned , return  information game. 

the aggregation be:

db.player.aggregate([     {$match:{ "id_device" : "machine1"}},     {$unwind: "$games"},     {$match:{ "games.gamename" : "ppa", "games.banned" : true}} ]) 

result

[      {         "_id" : objectid("569a30a30586bcb40f7d2531"),         "my_id" : "",         "id_device" : "machine1",         "language" : "italian",         "games" : {             "gamename" : "ppa",             "banned" : true,             "date" : isodate("2014-10-01t00:00:00.000z"),             "score" : 11         }     } ] 

some difference, if players may play same game more once (different date), can change aggregation pipelines.

{     "_id" : objectid("569a30a30586bcb40f7d2531"),     "my_id" : "",     "id_device" : "machine1",     "language" : "italian",     "games" : [          {             "gamename" : "ppa",             "banned" : false,             "date" : isodate("2014-10-01t00:00:00.000z"),             "score" : 11         },          {             "gamename" : "test2game",             "banned" : false,             "date" : isodate("2014-01-16t00:00:00.000z"),             "score" : 17         },          {             "gamename" : "ppa",             "banned" : true,             "date" : isodate("2014-04-18t00:00:00.000z"),             "score" : 23         },          {             "gamename" : "foo",             "banned" : true,             "date" : isodate("2015-03-03t00:00:00.000z"),             "score" : 2         },          {             "gamename" : "foo",             "banned" : false,             "date" : isodate("2015-04-28t00:00:00.000z"),             "score" : 2         }     ] } 

so query id_device , gamename "ppa", define our aggregation way:

db.player.aggregate([     {$match:{ "id_device" : "machine1"}},     {$unwind: "$games"},     {$match:{ "games.gamename" : "ppa"}},     {$group: {_id:{"_id":"$_id", "my_id":"$my_id", "id_device":"$id_device","language":"$language"}, "games" : {$push:"$games"}}},     {$project: {"_id":"$_id._id", "my_id":"$_id.my_id", "id_device": "$_id.id_device", "language":"$_id.language", "games":"$games"}} ]) 

result:

[      {         "_id" : objectid("569a30a30586bcb40f7d2531"),         "games" : [              {                 "gamename" : "ppa",                 "banned" : false,                 "date" : isodate("2014-10-01t00:00:00.000z"),                 "score" : 11             },              {                 "gamename" : "ppa",                 "banned" : true,                 "date" : isodate("2014-04-18t00:00:00.000z"),                 "score" : 23             }         ],         "my_id" : "",         "id_device" : "machine1",         "language" : "italian"     } ] 

as see, can add/modify pipeline steps , desired result.


Comments

Popular posts from this blog

get url and add instance to a model with prefilled foreign key :django admin -

css - Make div keyboard-scrollable in jQuery Mobile? -

ruby on rails - Seeing duplicate requests handled with Unicorn -