Mongodb String에서 ObjectId로 _id 필드에 가입
저는 두 개의 컬렉션을 가지고 있습니다.
사용자
{ "_id" : ObjectId("584aac38686860d502929b8b"), "name" : "John" }
역할.
{ "_id" : ObjectId("584aaca6686860d502929b8d"), "role" : "Admin", "userId" : "584aac38686860d502929b8b" }
userId(역할 컬렉션) - _id(사용자 컬렉션)를 기준으로 이러한 컬렉션에 참여하고 싶습니다.
다음 질문을 시도했습니다.
db.role.aggregate({
"$lookup": {
"from": "user",
"localField": "userId",
"foreignField": "_id",
"as": "output"
}
})
이것은 userId를 ObjectId로 저장하는 한 예상 결과를 제공합니다.userId가 문자열인 경우 결과가 없습니다.Ps: 노력했습니다.
외부 필드: '_id'.valueOf()
그리고.
외부 필드: '_id'.toString()
그러나 ObjectId 문자열 필드를 기준으로 일치/가입할 수 없습니다.
어떤 도움이든 감사하겠습니다.
문자열을 변환하는 mongodb 4.0의 집계를 사용할 수 있습니다.id
로.ObjectId
db.role.aggregate([
{ "$lookup": {
"from": "user",
"let": { "userId": "$_id" },
"pipeline": [
{ "$addFields": { "userId": { "$toObjectId": "$userId" }}},
{ "$match": { "$expr": { "$eq": [ "$userId", "$$userId" ] } } }
],
"as": "output"
}}
])
또는 mongodb 4.0의 집계를 사용하여 다음을 변환할 수 있습니다.ObjectId
로.String
db.role.aggregate([
{ "$addFields": { "userId": { "$toString": "$_id" }}},
{ "$lookup": {
"from": "user",
"localField": "userId",
"foreignField": "userId",
"as": "output"
}}
])
이것은 MongoDB 3.4 이후에는 불가능합니다.이 기능은 이미 요청되었지만 아직 구현되지 않았습니다.해당 티켓은 다음과 같습니다.
- SERVER-22781: ObjectId(_id.str)와 문자열 간에 $lookup 허용
- SERVER-24947: 불리언, 아이소데이츠, 객체에 대한 형식 변환 메커니즘 필요아이디
지금은 userId를 ObjectId로 저장해야 합니다.
편집
이전 티켓은 MongoDB 4.0에서 고정되었습니다.이제 다음 쿼리를 사용하여 이를 달성할 수 있습니다.
db.user.aggregate([
{
"$project": {
"_id": {
"$toString": "$_id"
}
}
},
{
"$lookup": {
"from": "role",
"localField": "_id",
"foreignField": "userId",
"as": "role"
}
}
])
결과:
[
{
"_id": "584aac38686860d502929b8b",
"role": [
{
"_id": ObjectId("584aaca6686860d502929b8d"),
"role": "Admin",
"userId": "584aac38686860d502929b8b"
}
]
}
]
온라인으로 시도해 보십시오: mongoplayground.net/p/JoLPVIb1OLS
이전 답변에 오류가 있는 것 같습니다.$toObjectId
케이스. 그let
문은 함수가 있는 DB 컬렉션에 적용됩니다.aggregate
는 "from"(즉, 'user')가 가리키는 컬렉션에서가 아니라 (즉, '역할')이라고 부릅니다.
db.role.aggregate([
{ "$lookup": {
"let": { "userObjId": { "$toObjectId": "$userId" } },
"from": "user",
"pipeline": [
{ "$match": { "$expr": { "$eq": [ "$_id", "$$userObjId" ] } } }
],
"as": "userDetails"
}}
])
또는
db.role.aggregate([
{ "$project": { "userObjId": { "$toObjectId": "$userId" } } },
{ "$lookup": {
"localField": "userObjId",
"from": "user",
"foreignField": "$_id",
"as": "userDetails"
}}
])
그리고.
db.user.aggregate([
{ "$project": { "userStrId": { "$toString": "$_id" }}},
{ "$lookup": {
"localField": "userStrId",
"from": "role",
"foreignField": "userId",
"as": "roleDetails"
}}
])
예를 들어 두 가지 컬렉션이 있습니다.
- {'_id'와 같은 작성자: ObjectId(), 이름: 'John Smith'}
- {'_id'와 같은 메시지: ObjectId(), 텍스트: '메시지 텍스트', 작성자ID: 'stringId'}
- 그리고 작성자 이름과 다른 데이터가 포함된 메시지를 받아야 합니다.
그러면:
db.messages.aggregate([
{
$addFields: {
'$authorObjectId': {$toObjectId: $authorId}
}
},
{
$lookup: {
from: 'authors',
localField: '$authorObjectId',
foreignField: '_id',
as: 'author'
}
}
])
설명:
NAT의 집계 파이프라인은 두 단계로 구성됩니다.
- 첫 번째: ObjectId()로 변환된 문자열 authorId가 포함된 메시지에 필드를 추가합니다.
- 둘째: 우리는 이 필드를 외부 필드 '_id'(작성자)와 비교하기 위해 localField(메시지)로 사용합니다.
언급URL : https://stackoverflow.com/questions/41093647/mongodb-join-on-id-field-from-string-to-objectid
'programing' 카테고리의 다른 글
Git 오류: src refspec 마스터가 일치하지 않습니다. (0) | 2023.05.17 |
---|---|
C#에서 배열에서 요소를 삭제하는 방법 (0) | 2023.05.17 |
Eclipse는 더 이상 참조를 강조 표시하지 않습니다. (0) | 2023.05.17 |
GitHub 메시지 의미: 전자 메일 개인 정보 보호 제한으로 인해 푸시가 거부되었습니다. (0) | 2023.05.17 |
npm 오류 "npm ERR! code ELIFECYCLE" 해결 방법 (0) | 2023.05.17 |