java—SpringMongo中有没有内置的函数可以用来从两个具有一对一关系的不同文档中提取数据?

ndasle7k  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(352)

我只是想在spring中使用mongo模板从mongodb中具有onetoone关系的两个不同文档中提取数据。
我有两个文档“rosters”(属于用户的嵌入文档)和“unread”都由“ucid”标识,这是“unique conversation identifier”的缩写。我想在ucid的基础上执行内部连接操作并提取数据。有很多例子表明,查找和聚合用于onetomany关系,而不用于onettoone。
以下是课程


**User**

class User
{
private List<Roster> rosterList;
}

**Roster**

public class Roster extends Parent
{
    @Id
    private ObjectId _id;
    @Indexed
    private String author;
@Unique
private String ucid;

}

**Unread**

public class
{
   @Id
    @Indexed(unique=true) //todo: create index on mongo side as well
    private String ucid;
private Map<String,Long> memberAndCount;

}

----------------------------------------------------
Sample Data:
USER (roster)
{user:{id:1001, username: dilag,roster:
[{
ucid:r0s122,name:sam}
},{
ucid:r0s123,name:ram}
},{
ucid:r0s124,name:rat}
}]}

UNREAD
{
ucid:r0s122,usernameAndCount:[{username:dilag,count:100},{username:ramg,count:20}],
ucid:r0s123,usernameAndCount:[{username:dilag,count:100},{username:ramg,count:20}]
}

Desired Output
{
ucid:r0s122, name :sam,usernameAndCount:[{username:dilag,count:100},{username:ramg,count:20}],
ucid:r0s123,name:ram,usernameAndCount:[{username:dilag,count:100},{username:ramg,count:20}]
}
yiytaume

yiytaume1#

下面的spring代码没有经过测试,但它是基于mongo平台编写的。
基本上,您需要知道如何使用 $lookup . 这里我使用了连接不相关的子查询

public List<Object> test() {
    Aggregation aggregation = Aggregation.newAggregation(
        l-> new Document("$lookup",
                new Document("from","user")
                .append("let", new Document("uid","$uicd"))
                .append("pipeline",
                    Arrays.asList(
                        new Document("$unwind", "$user.roster"),
                        new Document("$match",
                            new Document("$expr",
                                new Document("$eq",Arrays.asList("$user.roster.ucid","$$uid"))
                            )
                        )
                    )
                ).append("as","users")
        ),
        a-> new Document("$addFields",
                new Document("name",
                    new Document("$ifNull",
                        Arrays.asList(
                            new Document("$arrayElemAt", Arrays.asList("$users.user.roster.name",0))
                        ,
                        ""
                        )
                    )
                )
        )

    ).withOptions(AggregationOptions.builder().allowDiskUse(Boolean.TRUE).build());
    return mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(Unread.class), Object.class).getMappedResults();
}

阅读本文,了解在mongo-spring数据不提供任何操作的情况下如何进行聚合的技巧 new Document() .

相关问题