繁体   English   中英

如果数组中存在值,Spring Data MongoDB查询将添加布尔字段

[英]Spring data mongodb query add boolean field if value exists in array

我试图从mongoDb查询一些数据,其中包含喜欢数组。 每个喜欢的对象都包含喜欢者的user.id。

我需要一个额外的boolean字段,说明用户是否喜欢文档。 因此,如果用户喜欢该文档,则需要isLikedtrue

这是我到目前为止所做的:

我使用ConditionalOperators.Cond检查likes.userId是否等于访客的userId

    @Override
public List<PostExtra> findPostsNearBy(double[] point, Distance distance, String thisUserId) {
    mongoTemplate.indexOps(CheckInEntity.class).ensureIndex(new GeospatialIndex("position"));

    ConditionalOperators.Cond conditionalOperators = new ConditionalOperators.ConditionalOperatorFactory(Criteria.where("likes.userId").is(thisUserId)).then(true).otherwise(false);


    Aggregation aggregation = Aggregation.newAggregation(
            Aggregation.geoNear(
                    locationBasedOperationHelper.findNear(point,distance)
                        .query(new Query(privacyConsideredOperationHelper.privacyConsideredQuery(userRelationsEntity)))
                    ,"distance"
            ),
            //Aggregation.unwind("likes"),
            Aggregation.project("user", "description").and(conditionalOperators).as("isLiked")
    );

    final AggregationResults<PostExtra> results =
            mongoTemplate.aggregate(aggregation, PostEntity.class, PostExtra.class);
    return results.getMappedResults();
}

如果我删除Aggregation.unwind("likes")上的评论,则只能获得该用户不喜欢的帖子。

我在这里看到过同样的事情但是我不知道与MontoTemplate相关的MontoTemplate代码是什么? 我也看到了setIsSubset方法,但我仍然不知道Java实现。

我正在使用spring boot 2.0.4.RELEASEspring-boot-starter-data-mongodb


@Document(collection = EntityCollectionNames.POST_COLLECTION_NAME)
public class PostEntity{
    @Id
    private String id;
    @Field
    @DBRef
    @Indexed
    private UserEntity user;

    @GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE)
    @Field(value = "position")
    private Point position;

    @Field(value = "description")
    private String description;

    @Field
    private int likesCount;
    @Field
    private List<LikeEntity> likes;
}

发表额外:

public class PostExtra extends PostEntity {
    private double distance;
    private boolean isLiked;
}

喜欢:

public class LikeEntity {
    @Field
    private String userId;
}

经过一番搜索之后,我发现无需使用unwind即可做到这一点,我需要实现类似这样的功能来投影isLiked字段:

$cond:[
    {$gt:[
        {$size:
            {$setIntersection:["$likes.userId",userIdsToCheckIn]}
        },0]
    },true,false]

我试图在春天这样做:

    ConditionalOperators.Cond conditionalOperators = new ConditionalOperators.ConditionalOperatorFactory(
            ComparisonOperators.Gt.valueOf(
                ArrayOperators.Size.lengthOfArray(
                        SetOperators.SetIntersection.arrayAsSet("$likes.userId").intersects(????????)
                )
            ).greaterThanValue(0)
    ).then(true).otherwise(false);

但是我不知道该如何传递给intersects()方法,显然Spring不允许您将List或Array传递为该输入。 然后我发现我可以实现自己的AggregationExpressions并重写toDocument()方法。

所以我想出了这个,它起作用了:

ConditionalOperators.Cond conditionalOperators = new ConditionalOperators.ConditionalOperatorFactory(
                new AggregationExpression() {
                    @Override
                    public Document toDocument(AggregationOperationContext aggregationOperationContext) {
                        return Document.parse("{$gt:[{$size:{$setIntersection:[\"$likes.userId\",[\""+userId+"\"]]}},0]}");
                    }
                }
        ).then(true).otherwise(false);

当然,我也可以直接将$ cond添加到实现中。


我仍然想知道是否有任何不直接为此使用mongodb查询的spring解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM