문제

MongoDB에 중첩 된 세트 (댓글 나무와 같은)를 저장하는 모범 사례는 무엇입니까?

내 말은, 모든 의견은 부모의 의견과 자녀의 코멘트 (답변)를 가질 수 있습니다.

다음과 같이 저장 :

{
   title: "Hello",
   body: "Please comment me!",
   comments: [
        {
            author: "Peter",
            text: "Hi there",
            answers: [
                  {
                      author: "Peter",
                      text: "Hi there",
                      answers: [
                                 { author: "Ivan", text: "Hi there" },
                                 { author: "Nicholas", text: "Hi there" }
                      ]
                  },
                  { author: "Ivan", text: "Hi there" },
                  { author: "Nicholas", text: "Hi there" },
            ]
        },
        { author: "Ivan", text: "Hi there" },
        { author: "Nicholas", text: "Hi there" },
   ]
}

예를 들어, 우리는지도/축소없이 "Peter가 댓글을 달린 모든 게시물"을 요청할 수 없기 때문에 시원하지 않습니다.

도움이 되었습니까?

해결책

완벽한 솔루션은 없다고 생각합니다. 앱에 어떤 작업이 더 중요한지에 따라 다릅니다. 예를 들어 Silicon Alley Insider는 Mongodb가 둥지를 틀고 있다고 생각합니다. 그것은 당신이 언급하는 쿼리를 더 어렵게 만듭니다.

한 가지 옵션은 게시물의 최상위 수준에서 배열의 모든 댓글 작성자 목록입니다. 그것을 비정규 화 된 데이터로 생각하십시오. 그런 다음 특정 주석 자와 관련된 모든 게시물을 쉽게 찾을 수 있습니다. 그런 다음 드릴 다운하면 MAP/READER 또는 DB.EVAL ()을 사용하여 중첩 된 게시물 정보를 가져옵니다.

또 하나의 메모 - 단일 문서를 다루는 경우 DB.eval ()은 아마도 MAP/Reduce보다 가벼운 체중 일 것입니다. $는 옵션이지만 느리게 할 수 있으므로 위에서 언급 한 추가 '주석 자 목록'이 마음에 들기 때문에 배열도 쉽게 인덱싱하는 것이 아닙니다 (문서의 '멀티 키리'참조).

또한보십시오:http://groups.google.com/group/mongodb-user/browse_thread/thread/df8250573c91f75a/e880d9c57e343b52?lnk=gst&q=trees#e880d9c57e343b52

다른 팁

DM의 Post Dwight Merriman의 링크에서 Path Key를 사용하고 Regex Matches를 수행하는 것을 언급합니다.

{
  path : "a.b.c.d.e.f"
}

이를 수행하는 또 다른 방법은 배열입니다

{
  path : ["a", "b", "c", "d", "e", "f"]
}

db.test.ensureIndex({path: 1})

그것은 꽤 빨리 만들어야합니다.

각 노드가 단일 경로에만있을 수 있다면 목록의 위치에 대해 걱정할 필요가 없습니다.

db.test.find({path: "a"})

"a"의 모든 아이들을 찾을 것입니다

경로 이름 대신에 나는 아마도 노드의 _id를 사용할 것입니다.

업데이트

  • 조심해야 할 한 가지는 인덱스에 하나의 배열 만 가질 수 있다는 것입니다.
  • 쿼리에 설명을 사용해보십시오

    db.test.find ({path : {$ in : [ "a", "b"}))

당신을 준다

 db.test.find({path: {$in: ["a", "b"]}}).explain()
{
        "cursor" : "BtreeCursor path_1 multi",
        "nscanned" : 2,
        "nscannedObjects" : 2,
        "n" : 1,
        "millis" : 0,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : true,
        "indexOnly" : false,
        "indexBounds" : {
                "path" : [
                        [
                                "a",
                                "a"
                        ],
                        [
                                "b",
                                "b"
                        ]
                ]
        }
}

하지만

 db.test.find({path: {$all: ["a", "b"]}}).explain()
{
        "cursor" : "BtreeCursor path_1",
        "nscanned" : 1,
        "nscannedObjects" : 1,
        "n" : 1,
        "millis" : 0,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : true,
        "indexOnly" : false,
        "indexBounds" : {
                "path" : [
                        [
                                "a",
                                "a"
                        ]
                ]
        }
}

첫 번째 요소 만 사용한 다음 b에 대해 모든 일치하는 결과를 스캔합니다.
A가 루트 요소이거나 대부분의 레코드에있는 경우 효율적인 인덱스 쿼리 대신 레코드를 거의 완전히 스캔합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top