获取MongoDB Java中数组子文档字段的值。

huangapple go评论66阅读模式
英文:

Retrieve only the value of an arrays sub-document field using MongoDB Java

问题

我有一个数据库:

{
"_id": {
"$oid": "1"
},
"lastName": {
"lastName": "James"
},
"data": [{
"day": "20-09-2020 11:35:02",
"hoursWorked": "0小时:5分钟:321秒"
}, {
"day": "20-09-2020 11:35:29",
"hoursWorked": "0小时:5分钟:321秒"
}]
}

如何仅检索“data”字段的子字段“hoursWorked”的值。
因此,我只需要该字段的值或所有这些值,即0小时:5分钟:321秒。

我使用以下代码;然而,我仍然无法检索到该值。

Document document = collection
    .find(new BasicDBObject("_id", y))
    .projection(Projections.fields(Projections.include("data.hoursWorked"), excludeId())).first();
System.out.println(document);
}
英文:

I have a database:

{
"_id": {
    "$oid": "1"
},
"lastName": {
    "lastName": "James"
},
"data": [{
    "day": "20-09-2020 11:35:02",
    "hoursWorked": "0 hours : 5 mins : 321 secs"
}, {
    "day": "20-09-2020 11:35:29",
    "hoursWorked": "0 hours : 5 mins : 321 secs"
}]
}

How do I retrieve only the value of subfield "hoursWorked" of "data" field.
So, I need only the value or all values of such field, 0 hours : 5 mins : 321 secs.

I use the following; however, I still cannot retrieve the value.

Document document = collection
                .find(new BasicDBObject("_id", y))
                .projection(Projections.fields(Projections.include("data.hoursWorked"), excludeId())).first();
        System.out.println(document);
        }

答案1

得分: 1

使用 MongoDB Java 驱动程序

List<Bson> pipeline = 
    Arrays.asList(
        project(
             fields(
                 excludeId(), 
                 computed("hoursWorked", 
                      eq("$reduce", 
                          and(eq("input", "$data"), eq("initialValue", Arrays.asList()),
                              eq("in", eq("$concatArrays", Arrays.asList("$$value", Arrays.asList("$$this.hoursWorked")))) 
                          ) 
                      ) 
                  )
              )
          ),
         unwind("$hoursWorked")
    );
    
collection.aggregate(pipeline)
             .into(new ArrayList<Document>())
             .forEach(doc -> System.out.println(doc.get("hoursWorked")));

打印data数组中的两个值

0小时5分钟321秒
0小时5分钟322秒
英文:

Using MongoDB Java Driver:

List&lt;Bson&gt; pipeline = 
    Arrays.asList(
        project(
             fields(
                 excludeId(), 
                 computed(&quot;hoursWorked&quot;, 
                      eq(&quot;$reduce&quot;, 
                          and(eq(&quot;input&quot;, &quot;$data&quot;), eq(&quot;initialValue&quot;, Arrays.asList()),
                              eq(&quot;in&quot;, eq(&quot;$concatArrays&quot;, Arrays.asList(&quot;$$value&quot;, Arrays.asList(&quot;$$this.hoursWorked&quot;) ) ) ) 
                          ) 
                      ) 
                  ) 
              )
          ),
         unwind(&quot;$hoursWorked&quot;)
    );

collection.aggregate(pipeline)
             .into(new ArrayList&lt;Document&gt;())
             .forEach(doc -&gt; System.out.println(doc.get(&quot;hoursWorked&quot;)));

Prints two values from the data array:

0 hours : 5 mins : 321 secs
0 hours : 5 mins : 322 secs

答案2

得分: 0

你可以使用投影 $project

db.collection.aggregate([
  {
    $project: {
      "data.hoursWorked": 1
    }
  }
])

Mongo 游乐场 中运行

在 Spring Boot 中,你需要自动装配 mongoTemplate

@Autowired
MongoTemplate mongoTemplate;

聚合代码:

public List<Object> test(){
    Aggregation aggregation = Aggregation.newAggregation(
        a-> new Document("$project",
                new Document("data.hoursWorked", 1)
        )
    ).withOptions(AggregationOptions.builder().allowDiskUse(Boolean.TRUE).build());

    return mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(YOUR_COLLECTION.class), Object.class).getMappedResults();
}

更新 1

使用 Bson.Document

Document nodes = (Document) collection
        .find(new BasicDBObject("_id", "1"))
        .projection(Projections.fields(Projections.include("data.hoursWorked"), Projections.excludeId()))
        .first();

List<Document> list = (List<Document>) nodes.get("data");
for(Document d:list){
    System.out.println(d.get("hoursWorked"));
}
英文:

You can use projection $project.

db.collection.aggregate([
  {
    $project: {
      &quot;data.hoursWorked&quot;: 1
    }
  }
])

Working Mongo playground

In spring boot, you need to autowire the mongoTemplate

@Autowired
MongoTemplate mongoTemplate;

The aggregation code,

public List&lt;Object&gt; test(){
	Aggregation aggregation = Aggregation.newAggregation(
		a-&gt; new Document(&quot;$project&quot;,
				new Document(&quot;data.hoursWorked&quot;,1)
		)

	).withOptions(AggregationOptions.builder().allowDiskUse(Boolean.TRUE).build());

	return mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(YOUR_COLLECTION.class), Object.class).getMappedResults();
}

Update 1

Using Bson.Doument

Document nodes = (Document) collection
				.find(new BasicDBObject(&quot;_id&quot;, &quot;1&quot;))
				.projection(Projections.fields(Projections.include(&quot;data.hoursWorked&quot;), Projections.excludeId()))
				.first();

		List&lt;Document&gt; list = (List&lt;Document&gt;) nodes.get(&quot;data&quot;);
		for(Document d:list){
			System.out.println(d.get(&quot;hoursWorked&quot;));
		}

huangapple
  • 本文由 发表于 2020年9月21日 07:41:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/63984636.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定