Is there any in-built function in spring mongo which can be used to extract data from two different documents having onetoone relationship?

huangapple go评论82阅读模式
英文:

Is there any in-built function in spring mongo which can be used to extract data from two different documents having onetoone relationship?

问题

我只是在使用 Spring 中的 Mongo Template 从两个不同的 MongoDB 文档中提取数据,这两个文档具有一对一的关系。

我有两个文档 "Rosters"(属于用户的嵌入式文档)和 "Unread",它们都由 "ucid"(唯一会话标识符的首字母缩写)来标识。基于 ucid,我想执行内连接操作并提取数据。
有许多示例是针对一对多关系使用查找(lookup)和聚合(aggregation),但没有针对一对一关系的。

以下是类的定义:

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 Unread {
    @Id
    @Indexed(unique=true) //todo: 在 MongoDB 上创建索引
    private String ucid;
    private Map<String, Long> memberAndCount;
}

示例数据:

用户(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 }
    ]
}

期望的输出:

{
    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 }
    ]
}
英文:

I am just looking for extracting data from two different documents in mongodb having onetoone relationship using Mongo Template in spring.

I have two documents "Rosters" (Embedded Document belonging to User) and "Unread" both are identified by "ucid" an acronym for "unique conversation identifier". On the basis of ucid i'd like to perform inner-join operation and extract the data.
There are ample examples where lookup and aggregations are used for OneToMany Relationship but not for OnetToOne.

Following are the class

**User**
class User
{
private List&lt;Roster&gt; 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&lt;String,Long&gt; 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}]
}

答案1

得分: 1

以下是翻译好的部分:

下面的 Spring 代码尚未经过测试,但是基于可工作的 Mongo Playground 编写而成。

基本上你需要了解在 MongoDB 中使用 $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();
}

阅读此链接以了解如何在 MongoDB Spring Data 中使用 new Document() 进行聚合操作的技巧。

英文:

The following spring code is not tested, But it's written based on working Mongo playground.

Basically you need to know about joining in Mongodb using $lookup. Here I have used Joining Uncorrelated Sub-queries

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

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

Read this to understand the trick how to do aggregation if mongo spring-data doesn't provide any operation using new Document().

huangapple
  • 本文由 发表于 2020年8月22日 21:25:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/63536689.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定