Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java mongodb 3.0:在文档的内部数组中查找值_Java_Mongodb_Mongodb Java - Fatal编程技术网

java mongodb 3.0:在文档的内部数组中查找值

java mongodb 3.0:在文档的内部数组中查找值,java,mongodb,mongodb-java,Java,Mongodb,Mongodb Java,我正在使用java和mongodb v.3.0.7。 我有一个玩家列表,里面有一系列的游戏和分数。这是一个插入文档的测试: 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").i

我正在使用java和mongodb v.3.0.7。 我有一个玩家列表,里面有一系列的游戏和分数。这是一个插入文档的测试:

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)))
            );
}
new Document()
.append("gamename", "PPA")
.append("banned", false)
.append("date", format.parse("2014-10-01T00:00:00Z"))
.append("score", 11),
为了确定某个玩家是否被禁止参加某个特定的游戏,我将这样做:

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;
        }
    }
提供id_设备和游戏名?
谢谢

要实现这一点,您需要聚合数据。

根据您的用例,聚合可能会改变(更多查询,更多管道步骤)

以下是您的数据:

{
    "_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
        }
    ]
}
我假设:

You have a list of unique players. Each of them play unique games.
(Example: player1 never plays PPA twice) 
So, you need to search a game where the player is banned and return 
all information for that game.
汇总如下:

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

有些不同,如果您的玩家可能多次玩同一个游戏(不同的日期),您可以更改聚合管道

{
    "_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
        }
    ]
}
因此,为了查询id_设备和游戏名“PPA”,我们通过以下方式定义聚合:

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"}}
])
结果:


如您所见,您可以添加/修改管道步骤并获得所需的结果。

要实现这一点,您需要聚合数据。

根据您的用例,聚合可能会改变(更多查询,更多管道步骤)

以下是您的数据:

{
    "_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
        }
    ]
}
我假设:

You have a list of unique players. Each of them play unique games.
(Example: player1 never plays PPA twice) 
So, you need to search a game where the player is banned and return 
all information for that game.
汇总如下:

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

有些不同,如果您的玩家可能多次玩同一个游戏(不同的日期),您可以更改聚合管道

{
    "_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
        }
    ]
}
因此,为了查询id_设备和游戏名“PPA”,我们通过以下方式定义聚合:

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"}}
])
结果:


如您所见,您可以添加/修改管道步骤并获得所需的结果。

是。您的查找查询应该是这样的:
db.player.find({“id\u设备”:“machine1”,“games.gamename”:“PPA”,“games.banked”:true})
。如果存在,这将返回被禁止的玩家列表(
.size()
>0)。感谢您的回答,但我需要知道是否可能有嵌套文档或值,因为,例如,在将来,我需要使用id\u设备和gamename获取玩家的分数……是的,您可以。但是,您需要将
find
更改为
aggregate
。看看这篇文章,问题类似于如何通过查询获取/排除子文档。如果您愿意,我可以帮助您进行MongoDB shell查询,但是您需要更改为java。我尝试了AggregateIterable=db.getCollection(“player”).aggregate(asList(新文档($match),新文档(“id_设备”,id_设备)。append(“games.gamename”,“PPA”)),新文档($group),新文档(“id”,“id_设备”).append(“games.gamename”、“PPA”);但是给我错误,如果我删除append(“games.gamename”,“PPA”)只给我一条记录{{{id:machine1}},你能为你的用例提供更多细节吗?对于给定的玩家,游戏可以重复吗?你希望得到什么样的产出?是的。您的查找查询应该是这样的:
db.player.find({“id\u设备”:“machine1”,“games.gamename”:“PPA”,“games.banked”:true})
。如果存在,这将返回被禁止的玩家列表(
.size()
>0)。感谢您的回答,但我需要知道是否可能有嵌套文档或值,因为,例如,在将来,我需要使用id\u设备和gamename获取玩家的分数……是的,您可以。但是,您需要将
find
更改为
aggregate
。看看这篇文章,问题类似于如何通过查询获取/排除子文档。如果您愿意,我可以帮助您进行MongoDB shell查询,但是您需要更改为java。我尝试了AggregateIterable=db.getCollection(“player”).aggregate(asList(新文档($match),新文档(“id_设备”,id_设备)。append(“games.gamename”,“PPA”)),新文档($group),新文档(“id”,“id_设备”).append(“games.gamename”、“PPA”);但是给我错误,如果我删除append(“games.gamename”,“PPA”)只给我一条记录{{{id:machine1}},你能为你的用例提供更多细节吗?对于给定的玩家,游戏可以重复吗?您期望的具体输出是什么?