MongoDB Aggregation - 배열의 match if 값
집계를 수행하는 컬렉션이 있으며 기본적으로 다음과 같이 정리했습니다.
{array:[1,2,3], value: 1},
{array:[1,2,3], value: 4}
값이 배열에 있는지 확인하기 위해 집계 일치를 어떻게 수행합니까?사용해 보았습니다.{$match: {"array: {$in: ["$value"]}}}
하지만 아무것도 찾지 못합니다.
(위의 예를 들어) 출력은 다음과 같습니다.
{array:[1,2,3], value:1}
3.6 버전의 일반 쿼리에서 집계 표현식을 사용할 수 있습니다.
db.collection_name.find({"$expr": {"$in": ["$value", "$array"]}})
집계 사용:
사용할 수 있습니다.$match + $expr
현재의3.6
판본
db.collection_name.aggregate({"$match": {"$expr": {"$in": ["$value", "$array"]}}})
시도해 보세요$redact + $in
에 있어서의 표현.3.4
판본
db.collection_name.aggregate({
"$redact": {
"$cond": [
{
"$in": [
"$value",
"$array"
]
},
"$$KEEP",
"$$PRUNE"
]
}
})
앞서 설명한 바와 같이, 집계 파이프라인에서 논리를 계속할 필요가 없는 경우에는 이 옵션이 좋습니다.
그러나 사용하는 경우 를 사용하여 "값"을 배열로 변환하고 를 사용하여 비교합니다.다음을 사용하여 문서를 복제할 필요가 없으므로 이 방법이 가장 빠릅니다.
db.collection.aggregate([
{ "$redact": {
"$cond": {
"if": { "$setIsSubset": [
{ "$map": {
"input": { "$literal": ["A"] },
"as": "a",
"in": "$value"
}},
"$array"
]},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
파이프라인 연산자는 내부에서 논리 조건의 처리를 허용하고 논리 조건이 참인 문서를 "보관"하거나 조건이 거짓인 문서를 "제거"하기 위해 특수 작업을 사용합니다.
이를 통해 후속 제품과 동일하게 작동할 수 있지만 단일 파이프라인 단계가 더 효율적입니다.
이러한 연산자가 자바스크립트가 아닌 네이티브 코딩 연산자라는 점을 고려할 때, 일치를 수행하는 "가장 빠른" 방법일 가능성이 높습니다.따라서 MongoDB 2.6 이상 버전을 사용하는 경우 문서에서 이러한 요소를 비교하기 위해 이 방법을 사용해야 합니다.
@chridam의 대답에 기초한 약간의 변화:
db.test.aggregate([
{ "$unwind": "$array" },
{ "$group": {
_id: { "_id": "$_id", "value": "$value" },
array: { $push: "$array" },
mcount: { $sum: {$cond: [{$eq: ["$value","$array"]},1,0]}}
}
},
{ $match: {mcount: {$gt: 0}}},
{ "$project": { "value": "$_id.value", "array": 1, "_id": 0 }}
])
하는 것이 목적입니다.$unwind
그리고.$group
배열 뒤로, 카운트 인mcount
값과 일치하는 항목의 수입니다.그 후에, 간단한.$match
에mcount > 0
원하지 않는 문서를 필터링합니다.
보다 효율적인 접근 방식에는 다음과 같이 연산자를 사용하는 단일 파이프라인이 포함됩니다.
db.collection.aggregate([
{
"$redact": {
"$cond": [
{
"$setIsSubset": [
["$value"],
"$array"
]
},
"$$KEEP",
"$$PRUNE"
]
}
}
])
지원하지 않는 MongoDB의 이전 버전(버전 < 2.6)의 경우 연산자를 사용하는 이 집계 파이프라인을 고려하십시오.
db.collection.aggregate([
{ "$unwind": "$array" },
{
"$project": {
"isInArray": {
"$cond": [
{ "$eq": [ "$array", "$value" ] },
1,
0
]
},
"value": 1,
"array": 1
}
},
{ "$sort": { "isInArray": -1 } },
{
"$group": {
"_id": {
"_id": "$_id",
"value": "$value"
},
"array": { "$push": "$array" },
"isInArray": { "$first": "$isInArray" }
}
},
{ "$match": { "isInArray": 1 } },
{ "$project": { "value": "$_id.value", "array": 1, "_id": 0 } }
])
답변이 조금 늦었지만 이것은 또 다른 해결책을 제시합니다.
addFields와 match를 개별적으로 사용하면 수정보다 유연성이 높아집니다.여러 필드를 노출한 다음 결과에 따라 다른 일치 논리를 함께 사용할 수 있습니다.
db.applications.aggregate([
{$addFields: {"containsValueInArray": {$cond:[{$setIsSubset: [["valueToMatch"], "$arrayToMatchIn"]},true,false]}}},
{$match: {"containsValueInArray":true}}
]);
$eq와 $setIntersection의 조합을 시도합니다.
{$group :{
_id: "$id",
yourName : { $sum:
{ $cond :[
{$and : [
{$eq:[{$setIntersection : ["$someArrayField", ["$value"]] },["$value"]]}
]
},1,0]
}
} }
그룹화 없이 V.3.2 이후로 쉬운 접근 방식이 선호됩니다.
...aggregate([
{
$addFields: {
arrayFilter: {
$filter: {
input: '$array',
as: 'item',
cond: ['$$item', '$value']
}
}
}
},
{
$unwind: '$arrayFilter'
},
{
$project: {
arrayFilter: 0
}
}
]);
- 임시 필터 필드 추가
- 결과 어레이에 대한 $find(빈 어레이가 포함된 결과 제거)
- (선택사항) 프로젝트를 통해 결과에서 필터 필드 제거
간단한 $project & $match로 할 수 있습니다.
db.test.aggregate([{
$project: {
arrayValue: 1,
value: 1,
"has_same_value" : { $in: ["$value", "$arrayValue"] }
}
},
{
$match: {has_same_value: true}
},
{
$project: {has_same_value: 0}
}])
"$match": { "name": { "$in":["Rio","Raja"] }} }])
언급URL : https://stackoverflow.com/questions/30537317/mongodb-aggregation-match-if-value-in-array
'programing' 카테고리의 다른 글
Woocommerce의 각 3개 품목을 균일 요금으로 배송하는 데 추가 비용을 추가합니다. (0) | 2023.06.21 |
---|---|
SqlDateTime입니다.최소값!= 날짜 시간.MinValue, 왜? (0) | 2023.06.21 |
ORA-08177: 이 트랜잭션에 대한 액세스를 직렬화할 수 없습니다. (0) | 2023.06.21 |
node.js와 mongodb가 있는 전체 웹사이트? (0) | 2023.06.21 |
클래스에 대한 CSS의 와일드카드 * (0) | 2023.06.21 |