如何使用Java在MongoDB中将子文档(如果不存在)添加到数组字段?



我在Java中遇到一个非常简单的任务的问题: 我需要在对象内获取"用户"数组,

检查它是否包含密钥 ID,如果没有,则向阵列添加新用户。 我没有收到任何错误,但未添加用户。

请使用 Java 驱动程序回答。 为什么?这是代码:

List<DBObject> queryResultList = cursor.toArray(1);
DBObject currentObj = queryResultList.get(0);
Set userIdsKeySet = ((BasicDBObject) currentObj.get("users")).keySet();
BasicDBObject newObj = null;
if(!userIdsKeySet.contains(userId)){
((BasicDBList)currentObj.get("users")).add(new BasicDBObject().append(userId, user));
}
if(newObj != null) {
collection.update(currentObj, new BasicDBObject("users", newObj));
return true;
}

文档结构如下所示:

{
"_id": "5de9604ef36d7f394a4ade2f",
"_index": "sw0dfb0",
"users": [{
"e9604ef36d94a4ade7f394": {
"some_field": "abcde"
}
}]
}

以这种方式使用户阵列是更好的方法吗?

"users": [{
"user_id":"e9604ef36d94a4ade7f394",
"some_field":"abcde"
}]

注意:我知道有更漂亮,更简单的方法可以做到这一点,欢迎任何信息性建议。

我有一个Java示例程序,我不断地学习它。 我的例子可能有不适用的部分,但这里是问题的基础。 注意使用"$push"...

这假设有记录可用于查询和推送新的数组项...

package test.barry;
public class Main {
public static void main(String[] args) {
com.mongodb.client.MongoDatabase db = connectToClusterStandAlone();
InsertArrayItem(db);
return;
}

private static void InsertArrayItem(com.mongodb.client.MongoDatabase db) {
System.out.println("");
System.out.println("Starting InsertArrayItem...");
com.mongodb.client.MongoCollection<org.bson.Document> collection = db.getCollection("people");
com.mongodb.client.MongoCursor<org.bson.Document> cursor = collection.find(com.mongodb.client.model.Filters.eq("testfield", true)).sort(new org.bson.Document("review_date", -1)).limit(1).iterator();
if(cursor.hasNext()) {
org.bson.Document document = cursor.next();
Object id = document.get("_id");
System.out.println("Selected Id: " + id.toString());
org.bson.Document newDocument = new org.bson.Document("somekey", "somevalue");
collection.findOneAndUpdate(
com.mongodb.client.model.Filters.eq("_id", id),
new org.bson.Document("$push", new org.bson.Document("myarray", newDocument))
);  
}   

System.out.println("Completed InsertArrayItem.");
}
private static com.mongodb.client.MongoDatabase connectToClusterStandAlone() {
// STANDALONE STILL REQUIRES HOSTS LIST WITH ONE ELEMENT...
// http://mongodb.github.io/mongo-java-driver/3.9/javadoc/com/mongodb/MongoClientSettings.Builder.html
java.util.ArrayList<com.mongodb.ServerAddress> hosts = new java.util.ArrayList<com.mongodb.ServerAddress>();
hosts.add(new com.mongodb.ServerAddress("127.0.0.1", 27017));
com.mongodb.MongoCredential mongoCredential = com.mongodb.MongoCredential.createScramSha1Credential("testuser", "admin", "mysecret".toCharArray());
com.mongodb.MongoClientSettings mongoClientSettings = com.mongodb.MongoClientSettings.builder()
.applyToClusterSettings(clusterSettingsBuilder -> clusterSettingsBuilder.hosts(hosts))
.credential(mongoCredential)
.writeConcern(com.mongodb.WriteConcern.W1)
.readConcern(com.mongodb.ReadConcern.MAJORITY)
.readPreference(com.mongodb.ReadPreference.nearest())
.retryWrites(true)
.build();
com.mongodb.client.MongoClient client = com.mongodb.client.MongoClients.create(mongoClientSettings);
com.mongodb.client.MongoDatabase db = client.getDatabase("test");
return db;
}
}

运行两次后的示例文档...

{
"_id" : ObjectId("5de7f472b0ba4011a7caa59c"),
"name" : "someone somebody",
"age" : 22,
"state" : "WA",
"phone" : "(739) 543-2109",
"ssn" : "444-22-9999",
"testfield" : true,
"versions" : [
"v1.2",
"v1.3",
"v1.4"
],
"info" : {
"x" : 444,
"y" : "yes"
},
"somefield" : "d21ee185-b6f6-4b58-896a-79424d163626",
"myarray" : [
{
"somekey" : "somevalue"
},
{
"somekey" : "somevalue"
}
]
}

为了完整起见,这是我的 maven 文件...

Maven POM 文件...

<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>mongo-java-driver</artifactId>
<version>3.10.1</version>
</dependency>
</dependencies>
</project>

我有一个示例文档和Java代码(使用MongoDB Java Driver 3.9.0(来更新users数组。

MongoDB Enterprise > db.test.find()
{
"_id" : 1,
"index" : "999",
"users" : [
{
"user11" : {
"fld1" : "abcde"
}
},
{
"user22" : {
"fld1" : "xyz123"
}
}
]
}


爪哇代码:

import org.bson.Document;
import org.bson.conversions.Bson;
import com.mongodb.client.result.UpdateResult;
import static com.mongodb.client.model.Updates.*;
import static com.mongodb.client.model.Filters.*;
import com.mongodb.client.*;
public class Testing9 {
public static void main(String [] args) {
MongoClient mongoClient = MongoClients.create("mongodb://localhost/");
MongoDatabase database = mongoClient.getDatabase("users");
MongoCollection<Document> collection = database.getCollection("test");
String user = "user99"; // new user to be added to the array
Bson userNotExistsFilter = exists(("users." + user), false);
Bson idFilter = eq("_id", new Integer(1));
Document newUser = new Document(user, new Document("fld1", "some_value"));
Bson pushUser = push("users", newUser);
UpdateResult result = 
collection.updateOne(and(idFilter, userNotExistsFilter), pushUser);
System.out.println(result);
}
}


结果:

查询集合会显示与新用户"user99"users的更新数组字段:

MongoDB Enterprise > db.test.find().pretty()
{
"_id" : 1,
"index" : "999",
"users" : [
{
"user11" : {
"fld1" : "abcde"
}
},
{
"user22" : {
"fld1" : "xyz123"
}
},
{
"user99" : {
"fld1" : "some_value"
}
}
]
}



外壳查询:

这是来自mongo shell的等效更新查询:

db.test.updateOne(
{ _id: 1, "users.user99": { $exists: false} },
{ $push: { users: { user99: { fld1: "some_value" } } } }
)

集合的数组将添加以下文档:

{
"user99" : {
"fld1" : "some_value"
}
}

相关内容

最新更新