java 为什么这个mongodb搜索在Spring应用程序中失败?

eqoofvh9  于 2023-05-05  发布在  Java
关注(0)|答案(1)|浏览(204)

我正在Spring应用程序中使用mongodb进行以下搜索:

import org.bson.Document;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

private CampaignEntity incrByWithConversionRate(ObjectId campaignId, String key) {
    Query query = new Query();
    query.addCriteria(Criteria.where("id").is(campaignId));

    Update update = new Update();
    update.inc(key);
    update.set("conversionRate", new Document("$divide", Arrays.asList("$clicks", "$views")));

    return mongoTemplate.findAndModify(
        query, update,
        new FindAndModifyOptions().returnNew(true), CampaignEntity.class);
}

问题是它失败并出现以下错误:

org.springframework.data.mapping.MappingException: Expected to read Document Document{{$divide=[$clicks, $views]}} into type class java.lang.Float but didn't find a PersistentEntity for the latter!

注:CampaignEntity类定义如下:

@Data
@Document(collection = "campaigns")
public abstract class CampaignEntity extends BaseEntity {
    private Integer clicks = 0;
    private Integer views = 0;
    private Float conversionRate;
}
lsmepo6l

lsmepo6l1#

我最终使用了以下解决方案:

MnoCampaignEntity campaign = new MnoCampaignEntity();
campaign.setClicks(29);
campaign.setViews(5);
campaignRepository.save(campaign);

String query1 = "{$match: {_id: ObjectId(\"" + campaign.getId() + "\")}}";
String query2 = "{$project: {views: 1, clicks: {$add: [\"$clicks\", 1]}}}";
String query3 = "{$project: {views: 1, clicks: 1, conversionRate: {$cond: [{$eq: [\"$views\", 0]}, 0, {$divide: [\"$clicks\", \"$views\"]}]}}}";
String query4 = "{$merge: \"campaigns\"}";

TypedAggregation<MnoCampaignEntity> aggregation = Aggregation.newAggregation(
    MnoCampaignEntity.class,
    new CustomAggregationOperation(query1),
    new CustomAggregationOperation(query2),
    new CustomAggregationOperation(query3),
    new CustomAggregationOperation(query4)
);

mongoTemplate.aggregate(aggregation.withOptions(new AggregationOptions.Builder()
    .skipOutput()
    .allowDiskUse(true)
    .build()),
    "campaigns", MnoCampaignEntity.class);

CampaignEntity updated = campaignService.findById(campaign.getId().toString());
System.out.println("CONVERSION RATE: " + updated.getConversionRate());

注意:CustomAggregationOperation类来自this SO answer

相关问题