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
Post a Comment