如何使用java在mongodb中获取对象数组中的特定字段?

wr98u20j  于 2021-07-09  发布在  Java
关注(0)|答案(2)|浏览(414)

我在mongodb集合中有一个名为“usercollection”的数据,如下所示:

ID: "123"
name: "Tom"
age: 19
favprogram: (This is an Array)
{
    0: (This is an Object)
    {
        name: "Program"
        genre: "Thriller"
        programID: "001"
    }
    1:
    {
        name: "Program"
        genre: "Thriller"
        programID: "002"
    }
}

有些程序具有相同的名称,但它们的程序ID是唯一的。
在favprogram数组中创建对象的代码(它可以工作):

DBObject userQuery = new BasicDBObject("ID", 123);
DBObject favprogram = new BasicDBObject("favprogram", new BasicDBObject("name", "Program")
                            .append("genre", "Thriller")
                            .append("programID", "001"));
userCollection.update(userQuery, new BasicDBObject("$push", favprogram));

但是,以下代码无法从id为“123”的用户处获取programid。

DBObject query = new BasicDBObject("ID", "123");
DBCursor cursor = userCollection.find(query);
String programID = (String) cursor.next().get("favprogram.programID");

我的问题是,我想搜索一个特定的用户id(例如,“123”)并获取他的所有程序id。但似乎我永远也做不好(每次都是空的)。提前谢谢!

q3aa0525

q3aa05251#

我终于从id为“123”的用户那里获得了所有的程序id。

DBObject query = new BasicDBObject("ID", "123");
DBCursor cursor = userCollection.find(query);
// e.g. {"name": "Tom", "favprogram": {favprogram0, favprogram1, ... }}
BasicDBList favProgramList = (BasicDBList) cursor.next().get("favprogram");
// declare a String array
String [] programIDArray = new String[favProgramList.size()]
// iterate through the favProgramList
for (int i = 0; i < favProgramList.size(); i++) {
    DBObject result = (DBObject) favProgramList.get(i);
    programIDArray[i] = (String) result.get("programID");
}

现在,该用户的所有programid都被放入programidarray。

uujelgoq

uujelgoq2#

首先,你应该试着把你的json构造成有效的json——它可以帮助任何参与的人来帮助你。我假设你是从json开始的,类似于。。。

{
"_id" : ObjectId("6080b26dc05e721a15f04d37"),
"ID" : "123",
"name" : "Tom",
"age" : 19,
"favprogram" : [
    {
        "name" : "Program",
        "genre" : "Thriller",
        "programID" : "001"
    },
    {
        "name" : "Program",
        "genre" : "Thriller",
        "programID" : "002"
    }
]
}

假设这个json是正确的,我还假设您正在尝试构造以下聚合查询,但是使用java。。。

db.userCollection.aggregate([
{ $match : {
         "ID": "123"
    }
},
{ $unwind: { 
        path: "$favprogram",
        preserveNullAndEmptyArrays: true
    }
},
{
    $project: {
        _id: 0,
        "messageid": "$favprogram.programID"
    }
}
])

可能有很多方法可以满足你的要求,这只是一种方法。如果您觉得这个查询结构合适,那么这个java代码将执行这样一个聚合。。。

package test.barry;

public class Main {
    public static void main(String[] args) {

        // CONNECTION TO THE DATABASE
        // =============================

        com.mongodb.MongoClientSettings mongoClientSettings = com.mongodb.MongoClientSettings.builder()
                .applyConnectionString(new com.mongodb.ConnectionString("mongodb://testuser:mysecret@localhost:42011,localhost:42012,localhost:42013/?replicaSet=replSet&w=majority&readConcernLevel=majority&readPreference=primary&authSource=admin&retryWrites=true&maxPoolSize=10&waitQueueTimeoutMS=1000"))
                .build();

        com.mongodb.client.MongoClient client = com.mongodb.client.MongoClients.create(mongoClientSettings);

        com.mongodb.client.MongoDatabase db = client.getDatabase("javatest");
        com.mongodb.client.MongoCollection<org.bson.Document> collection = db.getCollection("userCollection");

        // QUERY THE DATABASE
        // ===================
        java.util.List<org.bson.conversions.Bson> pipeline = new java.util.ArrayList<org.bson.conversions.Bson>();

        org.bson.conversions.Bson filter = com.mongodb.client.model.Filters.eq("ID", "123");
        pipeline.add(com.mongodb.client.model.Aggregates.match(filter));

        com.mongodb.client.model.UnwindOptions unwindOptions = new com.mongodb.client.model.UnwindOptions();
        unwindOptions.preserveNullAndEmptyArrays(true);
        pipeline.add(com.mongodb.client.model.Aggregates.unwind("$favprogram", unwindOptions));

        pipeline.add(com.mongodb.client.model.Aggregates.project(
            com.mongodb.client.model.Projections.fields(
                com.mongodb.client.model.Projections.excludeId(), 
                com.mongodb.client.model.Projections.computed("messageid", "$favprogram.programID")) 
            )
        );

        com.mongodb.client.AggregateIterable<org.bson.Document> iterable1 = collection.aggregate(pipeline);

        // AUTO-CLOSABLE TRY
        try(com.mongodb.client.MongoCursor<org.bson.Document> cursor1 = iterable1.iterator())
        {
            while (cursor1.hasNext())
            {
                org.bson.Document queriedDocument1 = cursor1.next();
                System.out.println(String.format("messageid: %s", queriedDocument1.get("messageid")));
            }
        }
    }
}

下面是用于此程序的pom.xml。这个程序在提交前已经过测试。。。

<project
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>test.barry</groupId>
    <artifactId>test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>test</name>
    <url>http://maven.apache.org</url>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${basedir}</outputDirectory>
                            <finalName>Test</finalName>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>test.barry.Main</mainClass>
                                </transformer>
                            </transformers>
                            <createDependencyReducedPom>false</createDependencyReducedPom>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongodb-driver-sync</artifactId>
            <version>4.2.0</version>
        </dependency>
    </dependencies>
</project>

祝你好运!
顺便说一句,继续使用basicdbobject是进行此操作的旧方法。与bson助手相比,例如。。。

org.bson.conversions.Bson filter = com.mongodb.client.model.Filters.eq("_id", insertedDocument.get("_id"));
org.bson.conversions.Bson sort = com.mongodb.client.model.Sorts.ascending("lastName");
org.bson.conversions.Bson projection = com.mongodb.client.model.Projections.exclude("lastName");

相关问题