我有JSON
{
"responseCode": 200,
"productList": {
"count": 25,
"products": [
{
"id": 403492,
"description": null,
"plans": [
{
"name": "test1",
"type": "G"
},
{
"name": "test2",
"type": "Y"
}
]
}
],
}
}
而且我想获得仅针对“ G”类型的计划,但我不想将test2返回json
我尝试使用$ elemMatch但无法正常工作
Document query = new Document();
query.append("plans", new Document().append("$elemMatch", value));
最佳答案
显而易见,$elemMatch(query)是一种查询方法,用于在数组的元素与查询匹配时获取数据!
您想要的是$elemMatch(projection)!但是根据official document,此投影存在一个问题:
$运算符和$ elemMatch运算符都将投影第一个
根据条件匹配数组中的元素。
这意味着您将只获得与query匹配的第一个元素,
所以也许它不符合您的需求!
有两种方法:
1-在您的应用程序端投影所需的数据,也许使用java流api!
2-使用$filter(aggregation)
第二种方式(java代码):
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
import org.bson.conversions.Bson;
import java.util.Arrays;
import static com.mongodb.client.model.Aggregates.match;
import static com.mongodb.client.model.Aggregates.project;
import static com.mongodb.client.model.Filters.*;
public class Test {
public static void main(String[] args) throws Exception
{
MongoClient client = MongoClients.create(
"mongodb://localhost:27017"
);
MongoDatabase database = client.getDatabase("TEST");
MongoCollection<Document> documentMongoCollection =
database.getCollection("test");
Document document = documentMongoCollection.aggregate(
Arrays.asList(
match(elemMatch("productionList.products.plans" , eq("type" ,"G")))
,project(new Document("productionList.products" ,
map("productionList.products" , "this" ,
new Document("plans" ,
filter("$this.plans" ,
"plan" ,
new Document(
"$eq" ,
Arrays.asList("$$plan.type" , "G")
)))
.append("description" , "$$this.description")//make it present
.append("id" , "$$this.id"))) //make it present
.append("responseCode" , 1) //include
.append("productionList.count" , 1) //include
)
)).first();
System.out.println(document.toJson());
}
private final static Bson filter(String arrayName , String as , Bson cond)
{
//so to do it !
Document document = new Document("input" , "$"+arrayName);
if(as!=null && !as.isEmpty())
document.append("as" , as);
document.append("cond" , cond);
return new Document("$filter" , document);
}
private final static Bson map(String arrayName ,String as , Bson in)
{
Document document = new Document("input" , "$"+arrayName);
if(as!=null && !as.isEmpty())
document.append("as" , as);
document.append("in" , in);
return new Document("$map" , document);
}
}
也许很难理解我在这段代码上写的内容,您需要检查以下链接:
$map(aggregation)
$expr
$project(aggregation)
关于java - $ elemMatch使用Java对嵌套数组进行过滤,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60743947/