Aggregate의 투영에서 $elemMatch를 사용하는 방법은 무엇입니까?
내 목표는 다음과 같습니다.
{ "_id" : ObjectId("53fdcb6796cb9b9aa86f05b9"), "list" : [ "a", "b" ], "complist" : [ { "a" : "a", "b" : "b" }, { "a" : "c", "b" : "d" } ] }
그리고 이것이 제가 이루고 싶은 것입니다: "list"에 특정 요소가 포함되어 있는지 확인하고 이러한 값에 상관없이 문서를 읽는 동안 "complist"에 있는 개체에서 필드 "a"만 가져옵니다.포럼 시스템을 만들고 있습니다. 포럼의 세부 정보를 반환하는 쿼리입니다.사용자가 포럼 화이트리스트에 있는지 확인하는 동안 포럼 정보를 읽어야 합니다.
찾기를 사용하여 쿼리를 사용할 수 있습니다.
db.itens.find({},{list:{$elemMatch:{$in:["a"]}}})
특정 값과 일치하는 첫 번째 요소만 가져옵니다.이렇게 하면 반환된 배열이 비어 있지 않은지 확인할 수 있으며 "list"에 내가 찾고 있는 값이 포함되어 있는지 확인할 수 있습니다."리스트" 값에서 찾고 있는 값이 포함된 문서를 원하기 때문에 쿼리에서 할 수 없습니다.저는 그 문서가 필요하고 "리스트"에 어떤 가치가 있는지 알고 싶습니다.
Aggregate를 사용하면 쿼리를 사용할 수 있습니다.
db.itens.aggregate({$project:{"complist.a":1}})
completist에 포함된 객체의 필드 "a"만 읽습니다.이것은 포럼의 스레드에 대한 기본 정보를 얻을 것입니다. 저는 스레드에 대한 모든 정보를 원하지 않습니다. 단지 몇 가지를 원합니다.
하지만 제가 쿼리를 사용하려고 할 때
db.itens.aggregate({$project:{"complist.b":1,list:{$elemMatch:{$in:["a"]}}}})
두 가지를 모두 시도하면 연산자 $elemMatch가 유효하지 않다는 오류가 발생합니다.
제가 $elemMatch 합계로 여기서 뭔가 잘못하고 있나요?이것을 달성할 수 있는 더 좋은 방법이 있습니까?
꽤 오래된 질문이지만 말 그대로 제안된 답변 중 어떤 것도 좋지 않습니다.
TLDR:
$프로젝트 단계에서 $elemMatch를 사용할 수 없습니다.그러나 $filter와 같은 다른 집계 연산자를 사용하여 동일한 결과를 얻을 수 있습니다.
db.itens.aggregate([
{
$project: {
compList: {
$filter: {
input: "$complist",
as: "item",
cond: {$eq: ["$$item.a", 1]}
}
}
}
}
])
그리고 $elemMatch와 유사한 조건과 일치하는 배열의 첫 번째 항목만 원한다면 $array를 통합할 수 있습니까?엘렘앳
상세한 설명:
먼저 $elemMatch에 대해 알아보겠습니다.
$elemMatch는 쿼리 식이지만 이 투영 버전은 $project 집계 단계가 아닌 쿼리 투영을 나타냅니다.
그래서 어쩌라고이것이 어떤 것과 관련이 있습니까? 글쎄요, $프로젝트 단계는 특정 입력 구조를 가질 수 있는 반면, 우리가 사용하고자 하는 것은 다음과 같습니다.
<field>: <해석>
올바른 표현식은 무엇입니까?
식에는 필드 경로, 리터럴, 시스템 변수, 식 개체 및 식 연산자가 포함될 수 있습니다.식을 중첩할 수 있습니다.
그래서 우리는 표현 연산자를 사용하고 싶지만, 의사의 진단서에서 볼 수 있듯이.$elemMatch그것의 일부가 아닙니다.따라서 집계에 사용할 수 있는 올바른 식을 사용할 수 없습니다.$project 무대.
어떤 이유에서인지 $elemMatch는 집계에서 작동하지 않습니다.당신은 Mongo 3.2의 새로운 $filter 연산자를 사용해야 합니다.https://docs.mongodb.org/manual/reference/operator/aggregation/filter/ 을 참조하십시오.
db.collection_name.aggregate({
"$match": {
"complist": {
"$elemMatch": {
"a": "a"
}
}
}
});
사실, 가장 간단한 해결책은 배열을 $unwind한 다음 해당 문서를 $match하는 것입니다.$group 및 $push를 사용하여 해당 문서를 다시 와인딩할 수 있습니다.
질문이 오래되었지만, 2017년 11월에 대한 저의 기고문입니다.
저도 비슷한 문제가 있었고 두 번 연속으로 경기를 하는 것이 저에게 효과가 있었습니다.아래 코드는 제 전체 코드의 하위 집합이고 요소 이름을 변경했기 때문에 테스트되지 않았습니다.어쨌든 이것은 당신을 올바른 방향으로 이끌 것입니다.
db.collection.aggregate([
{
"$match": {
"_id": "ID1"
}
},
{
"$unwind": "$sub_collection"
},
{
"$match": {
"sub_collection.field_I_want_to_match": "value"
}
}
])
의 경우 집의경다사용을을 .$expr:
db.items.aggregate([
{
"$match": {
"$expr": {"$in": ["a", "$list"]}
}
},
])
문서를 간단히 풀고 ID별로 다시 그룹화할 수 있습니다.
{ $unwind: "$yourarray" },
{
$match: {
"field": { $gt: 1 }
},
},
{
$group: {
_id: "$_id"
}
},
배열을 사용할 수 있습니다.find의 투영 블록에 "field"를 입력합니다.
db.itens.find({},{"complist.b":1,list:{$elemMatch:{$in:["a"]}}})
내가 필요한 걸 해줬어요
언급URL : https://stackoverflow.com/questions/25528217/how-to-use-elemmatch-on-aggregates-projection
'programing' 카테고리의 다른 글
| MVC 4 또는 5를 사용하는 MEF - Pluggable Architecture(2014) (0) | 2023.06.27 |
|---|---|
| 시스템에서 GetActiveObject에 대한 정의를 찾을 수 없습니다.런타임.Interop Services.C# 원수 (0) | 2023.06.22 |
| ASP.NET MVC에서 부분 보기용 컨트롤러 생성 (0) | 2023.06.22 |
| SQL - 소수 뒤의 숫자만 가져오려면 어떻게 해야 합니까? (0) | 2023.06.22 |
| Sql JOIN 순서가 성능에 영향을 미칩니까? (0) | 2023.06.22 |