글쎄, 분명히 여기에 제시된 사례에 대한 추가 사용 패턴이 제대로 작동하도록 "목록"문서에 이러한 것을 포함시키는 것이 좋습니다. 그걸 염두에두고 버릴 이유가 없습니다.
{
"_id": "sdf3f",
"likedBy": [
{ "userId": "12ac", "date": ISODate("2014-04-09T07:30:47.091Z") },
{ "userId": "as3vd", "date": ISODate("2014-04-09T07:30:47.091Z") },
{ "userId": "sadf3", "date": ISODate("2014-04-09T07:30:47.091Z") }
],
"dislikedBy": [
{ "userId": "asdf", "date": ISODate("2014-04-09T07:30:47.091Z") },
{ "userId": "sdsdf", "date": ISODate("2014-04-09T07:30:47.091Z") },
{ "userId": "asdfas", "date": ISODate("2014-04-09T07:30:47.091Z") }
],
"active": true
}
하나 개 잡기가 있다는 것을 제외하고는 모두 잘 괜찮 :하지만 명확하게
, 당신이 원하는 것처럼 보이는 구조는 다음과 같은 것입니다. 두 개의 배열 필드에이 내용이 있으므로 두 필드 모두에 대해 색인을 만들 수는 없습니다. 이는 하나의 배열 유형의 필드 (또는 다중 키) 만 복합 인덱스에 포함될 수있는 제한 사항입니다.
그래서 첫 번째 쿼리가 인덱스를 사용 할 수없는에 명백한 문제를 해결하기 위해, 당신은 대신이 같은 구조 것입니다 :
db.post.ensureIndex({
"active": 1,
"votes.userId": 1,
"votes.date": 1,
"votes.type": 1
})
:
{
"_id": "sdf3f",
"votes": [
{
"userId": "12ac",
"type": "like",
"date": ISODate("2014-04-09T07:30:47.091Z")
},
{
"userId": "as3vd",
"type": "like",
"date": ISODate("2014-04-09T07:30:47.091Z")
},
{
"userId": "sadf3",
"type": "like",
"date": ISODate("2014-04-09T07:30:47.091Z")
},
{
"userId": "asdf",
"type": "dislike",
"date": ISODate("2014-04-09T07:30:47.091Z")
},
{
"userId": "sdsdf",
"type": "dislike",
"date": ISODate("2014-04-09T07:30:47.091Z")
},
{
"userId": "asdfas",
"type": "dislike",
"date": ISODate("2014-04-09T07:30:47.091Z")
}
],
"active": true
}
이이 양식을 포함하는 인덱스를 할 수 있습니다
실제로 사용 패턴에 따라 몇 가지 인덱스가 필요할 수 있지만 포인트에 이제는 사용할 수있는 인덱스가있을 수 있습니다.
당신이 쿼리의이 양식을 가지고 첫 번째 경우를 커버 :
명확 각 사용자에 대한 추천하고 싫어하는 옵션 모두를하지 않을 것을 고려 의미가
db.post.find({ "active": true, "votes.userId": { "$ne": "12ac" } })
. 해당 색인의 순서에 따라 최소 활성 상태는 필터링 조건을 부정적인 조건으로 모두 스캔해야하기 때문에 필터링 할 수 있습니다. 어떤 구조로든 그럴 수 있습니다.
다른 경우에는 userId가 날짜 이전의 색인에 있고 첫 번째 요소로 사용되기를 원할 것입니다. 그런 다음 쿼리가 매우 간단합니다 :
db.post.find({ "votes.userId": "12ac" })
.sort({ "votes.userId": 1, "votes.date": 1 })
하지만 갑자기 뭔가를 잃었다 궁금 할 수, "좋아"와 "싫어"의 카운트가 전에 배열의 크기를 테스트 한 쉬웠다 받고 있지만, 이제는 조금 다릅니다. 아니 집계하여 해결할 수없는 문제 : 그룹화 _id
을 유지하고 "좋아"와 "싫어의 수를 평가하기 위해 문서의 중요한 부분을 저장할 수있는 어떤 실제 사용 형태
db.post.aggregate([
{ "$unwind": "$votes" },
{ "$group": {
"_id": {
"_id": "$_id",
"active": "$active"
},
"likes": { "$sum": { "$cond": [
{ "$eq": [ "$votes.type", "like" ] },
1,
0
]}},
"dislikes": { "$sum": { "$cond": [
{ "$eq": [ "$votes.type", "dislike" ] },
1,
0
]}}
])
그래서를 "쉬운 방법으로.
같은 항목에서 싫어하는 항목으로 변경하는 작업은 단일 원자 업데이트로 수행 할 수도 있습니다.
할 수있는 일이 훨씬 더 많지만 주어진 이유로이 구조를 선호합니다.
실제로 사용법을 말할 의도가 없을 때 어떤 종류의 스키마를 사용하는지에 대해 누구나 언급하기가 어렵습니다. 아마도 타임 스탬프 정보를 추가해야하는 이유가있을 수 있습니다. 공유 한 경우 질문에 사용하려면 답할 것이 있습니다. –
감사합니다. @NeilLunn, 이해하기 쉽게하기 위해 다시 작성했습니다. 기본적으로 나는 선택한 모든 목록과 'likes'와 'dislikes'에 대한 사용자의 기록을 얻기위한 별도의 쿼리를 찾기 위해 쿼리를 실행할 수 있어야합니다. – SkinnyGeek1010