San Jaisy
San Jaisy

Reputation: 17128

Filter embedded Array object in mongodb document using Java driver

I have the below data, and I want to filter the data for _id = "63283dd5777142017baa763b" and subCategory._id = "63283e25777142017baa7641"

{
    "_id": ObjectId("63283dd5777142017baa763b"),
    "name": "Men",
    "description": "Men",
    "subCategory": [{
            "name": "ssss",
            "description": "ss",
            "_id": ObjectId("63283e1f777142017baa7640")
        },
        {
            "name": "aa",
            "description": "aa",
            "_id": ObjectId("63283e25777142017baa7641")
        }
    ]
}

Using the MongoClient as below

@Singleton
public record MongoDbRepository(MongoClient mongoClient, MongodbConfiguration mongodbConfiguration) implements IMongoRepository {
    @Override
    public <T> MongoCollection<T> getCollection(String collectionName, Class<T> typeParameterClass) {
        return mongoClient
                .getDatabase(mongodbConfiguration.database())
                .getCollection(collectionName, typeParameterClass);
    }
}

And fetching the data from MongoClient

@Override
public Mono<SubCategoryModel> find(String categoryId, String id) {
    Bson query = filters.add(and(eq("_id", new ObjectId(categoryId)),eq("subCategory._id", new ObjectId(id))));
    return Mono.from(iMongoRepository.getCollection(ConstantValues.PRODUCT_CATEGORY_COLLECTION_NAME, Category.class)
                    .find(query))
            .map(item -> {
                var element = item.getSubCategory().stream().findFirst().get();
                return new SubCategoryModel(element.get("_id").toString(), element.get("name").toString(), element.get("description").toString());
            });
}

With the filter filters.add(and(eq("_id", new ObjectId(categoryId)),eq("subCategory._id", new ObjectId(id)))), its returning both the value. Its not filtering subCategory._id = ObjectId("63283e25777142017baa7641")

Upvotes: 0

Views: 236

Answers (1)

Charchit Kapoor
Charchit Kapoor

Reputation: 9284

I think you need to provide a projection as well, to pick on the matched array element, like this:

@Override
public Mono<SubCategoryModel> find(String categoryId, String id) {
    Bson query = filters.add(and(eq("_id", new ObjectId(categoryId)),eq("subCategory._id", new ObjectId(id))));
    Bson projectionFields = Projections.fields(Projections.include("name", "description", "subCategory.$"));
    return Mono.from(iMongoRepository.getCollection(ConstantValues.PRODUCT_CATEGORY_COLLECTION_NAME, Category.class)
                    .find(query).projection(projectionFields))
            .map(item -> {
                var element = item.getSubCategory().stream().findFirst().get();
                return new SubCategoryModel(element.get("_id").toString(), element.get("name").toString(), element.get("description").toString());
            });
}

Upvotes: 0

Related Questions