동일한 문서의 필드가 있는 Mongodb 쿼리
다음과 같은 json이 있습니다.
{
"a1": {"a": "b"},
"a2": {"a": "c"}
}
다음 위치에서 모든 문서를 요청하려면 어떻게 해야 합니까?a1그리고.a2동일한 문서에서 동일하지 않습니까?
다음을 사용할 수 있습니다.
db.myCollection.find( { $where: "this.a1.a != this.a2.a" } )
그러나 자바 스크립트 엔진을 회전시켜 각 문서를 반복하고 각 문서의 상태를 확인해야 하므로 이 작업은 그리 빠르지 않습니다.
이 매우 수행해야 할 에는 모대컬에대수야행하거매나해우자주수하행다는좋니습과 정규화되지 플래그를 이 가장 .areEqual여전히, 그러한 낮은 선택성 필드는 후보 집합이 여전히 크기 때문에 좋은 인덱스 성능을 산출하지 못합니다.
갱신하다
mongo 3.6 현재 사용 가능한 새로운 $expr 연산자를 사용하여 다음과 같은 find 쿼리에서 집계 표현식을 사용할 수 있습니다.
db.myCollection.find({$expr: {$ne: ["$a1.a", "$a2.a"] } });
이 의견으로 문제가 해결되었지만, 이 사용 사례와 더 잘 맞는 것은 $project 대신 버전 3.4에서 사용 가능한 $addFields 연산자를 사용하는 것이라고 생각합니다.
db.myCollection.aggregate([
{"$match":{"a1":{"$exists":true},"a2":{"$exists":true}}},
{"$addFields": {
"aEq": {"$eq":["$a1.a","$a2.a"]}
}
},
{"$match":{"aEq": false}}
]);
JavaScript를 방지하려면 집계 프레임워크를 사용합니다.
db.myCollection.aggregate([
{"$match":{"a1":{"$exists":true},"a2":{"$exists":true}}},
{"$project": {
"a1":1,
"a2":1,
"aCmp": {"$cmp":["$a1.a","$a2.a"]}
}
},
{"$match":{"aCmp":0}}
])
개발 서버에서 동일한 JavaScript 쿼리를 완료하는 데 7배 더 오래 걸립니다.
업데이트(2017년 5월 10일)
저는 제 대답이 동등하지 않은 가치를 원하는 질문에 대답하지 않았다는 것을 깨달았습니다(때로는 제가 정말 느릴 때도 있습니다).이 작업은 다음과 같습니다.
db.myCollection.aggregate([
{"$match":{"a1":{"$exists":true},"a2":{"$exists":true}}},
{"$project": {
"a1":1,
"a2":1,
"aEq": {"$eq":["$a1.a","$a2.a"]}
}
},
{"$match":{"aEq": false}}
])
$ne대신 사용할 수 있습니다.$eq이 기조건로변경우경된으로 true하지만 저는 그것을 사용합니다.$eq와 함께false좀 더 직관적으로.
MongoDB는 백그라운드에서 Javascript를 사용하기 때문에
{"a": "b"} == {"a": "b"}
되요지일 입니다.false.
따라서 각각을 비교하려면 a1.a == a2.a가 필요합니다.
MongoDB에서 이 작업을 수행하려면 $where 연산자를 사용합니다.
db.myCollection.find({$where: "this.a1.a != this.a2.a"});
이것은 내장된 각 문서가 속성 "a"를 갖는다고 가정합니다.그렇지 않으면 일이 더 복잡해집니다.
에서 시작Mongo 4.4원시 값뿐만 아니라 하위 값을 비교하려는 사람들을 위해(이후).{"a": "b"} == {"a": "b"}이라false), 사용자 정의 Javascript 함수를 적용할 수 있는 새로운 집계 연산자를 사용할 수 있습니다.
// { "a1" : { "x" : 1, "y" : 2 }, "a2" : { "x" : 1, "y" : 2 } }
// { "a1" : { "x" : 1, "y" : 2 }, "a2" : { "x" : 3, "y" : 2 } }
db.collection.aggregate(
{ $match:
{ $expr:
{ $function: {
body: function(a1, a2) { return JSON.stringify(a1) != JSON.stringify(a2); },
args: ["$a1", "$a2"],
lang: "js"
}}
}
}
)
// { "a1" : { "x" : 1, "y" : 2 }, "a2" : { "x" : 3, "y" : 2 } }
$function세 가지 매개 변수를 사용합니다.
body이는 적용할 함수이며 매개 변수는 비교할 두 필드입니다.args여기에는 레코드의 필드가 포함되어 있습니다.body함수는 매개 변수로 사용됩니다. 에는 둘 다."$a1"그리고."$a2".lang그것이 그 언어입니다.body함수가 작성되었습니다..js현재 사용할 수 있습니다.
aggregate()를 사용하는 답변과 관련하여 처음에 저를 혼란스럽게 했던 한 가지는 $eq(또는 $in 또는 많은 다른 연산자)가 사용되는 위치에 따라 다른 의미를 가지고 있다는 것입니다.find() 또는 $match 집계 단계에서 $eq는 단일 값을 사용하고 일치하는 문서를 선택합니다.
db.items.aggregate([{$match: {_id: {$eq: ObjectId("5be5feb45da16064c88e23d4")}}}])
그러나 $project 집계 단계에서 $eq는 2개의 식을 사용하고 값이 true 또는 false인 새 필드를 만듭니다.
db.items.aggregate([{$project: {new_field: {$eq: ["$_id", "$foreignID"]}}}])
프로젝트에서 사용한 쿼리는 버그로 인해 링크된 항목 목록이 자신과 연결된 모든 항목을 찾는 데 사용되었습니다.
db.items.aggregate([{$project: {idIn: {$in: ["$_id","$header.links"]}, "header.links": 1}}, {$match: {idIn: true}}])
언급URL : https://stackoverflow.com/questions/8433046/mongodb-query-with-fields-in-the-same-documents
'programing' 카테고리의 다른 글
| xcode에서 iOS App 아카이브를 생성할 수 없습니다. (0) | 2023.05.04 |
|---|---|
| 파일 중간에 특정 행을 표시하는 빠른 unix 명령? (0) | 2023.05.04 |
| Postgresql 스키마 경로 영구 설정 (0) | 2023.05.04 |
| ASP에서 사용자 정의 오류 페이지를 작동시키는 방법.NET MVC 4 (0) | 2023.05.04 |
| postgres에서 중복 어레이 값 제거 (0) | 2023.05.04 |