2014-11-03 9 views
1

Meteor 애플리케이션에서 태그 필드가있는 문고 컬렉션이 있습니다.유성 및 몽고 및 꼬인 태그 태그

[{name: "ABC", tags: {"@Movie", "#free", "!R"}}, 
{name: "DEF", tags: {"@Movie", "!PG"}}, 
{name: "GHI", tags: {"@Sports", "#free"}}] 

내 UI에는 태그 이름의 첫 글자를 기반으로 즉석에서 채워지는 세 개의 체크 박스 그룹이 있습니다. 필터 그룹은 필터 그룹에서 체크 박스가 체크되는 필터 그룹

  • 만약에 의해 필터링하지 않는 다음 비어

    • 경우 해당 필터를 적용 :

      filter group 1: [ ]Movie [ ] Sports 
      filter group 2: [ ]free 
      filter group 3: [ ]PG [ ]R 
      

      필터 논리는 다음과 같다

    • $ 필터 그룹간에 적용해야합니다 (영화 및 R을 선택한 경우 "! 영화"및 "# 무료"라는 태그가있는 문서 만 선택해야합니다)

    위의 논리를 따르는 mongo criteria 매개 ​​변수를 작성하는 데 어려움을 겪고 있습니다. 내 코드는 현재 (의사 코드에서) 중첩 된 ifs가 많은 스파게티처럼 보입니다.

    (filter_group1이 비어 있으면) 그러면 if (filter_group2가 비어있는 경우) 다음 mongo_criteria = {_id : $ in : $ ("input : checked" ".filtergroup1"). map (function() {return this.value})}

    이 작업을 수행하는 올바른 방법은 무엇입니까?

  • 답변

    2

    첫째, 난 당신이 "태그"그렇지 않으면 구조가 유효하지 않을 것이기 때문에 배열 실제로는 것을 의미 확신 :

    { "name": "ABC", "tags": ["@Movie", "#free", "!R"]}, 
    { "name": "DEF", "tags": ["@Movie", "!PG"]}, 
    { "name": "GHI", "tags": ["@Sports", "#free"]} 
    

    그것은 "태그"데이터 이런 식으로 저장하는 새로운 아이디어가 있지만, 쿼리를 구성하는 프로그램 논리가 $and 조합에서 고려해야 할 최소한 "3 가지"가능한 조건이 있음을 인식해야합니다.

    필터 그룹 당 하나의을 선택하는 것이 가장 간단한 형식에서 $all 연산자를 사용하면이 문제를 해결할 수 있습니다. 그냥 간결에 대한 간단한 MongoDB의 쉘 표기법 :

    db.collection.find({ "tags": { "$all": [ "@Movie", "!R" ] } }) 
    

    문제가 당신이 그룹에 복수 선택을 원하는 경우에는 평가가 예를 들어, 다음이 결과 얻기 위해 실패 말할 것입니다 :

    db.collection.find({ "tags": { "$all": [ "@Movie", "!R", "!PG" ] } }) 
    

    실제로 두 평가 값이 모두 포함 된 항목이 없으므로 유효하지 않습니다. 따라서 다음과 같이하십시오.

    모든 영화는 "R"및 "PG"등급 태그와 정확하게 일치합니다. 일치하는 값으로 필터의 그 "유형"을 각각있는 경우에만 문서를 얻기

    db.collection.find({ "$and": [ 
        { "tags": { "$in": [ "@Movie" ] } }, 
        { "tags": { "$in": [ "!R", "!PG" ] } }, 
        { "tags": { "$in": [ "#free" ] } 
    ]) 
    

    , 그래서 "PG"영화가되지 않습니다 : 다른 그룹이 확장은 기본적으로 $and 표현에 다른 배열 항목을 추진하고있다 무료이고 "스포츠"는 선택 항목에 추가하지 않음으로써 필터링되었습니다.

    쿼리를 구성하는 기본 사항은 각 필터 그룹에서 $in에 대한 선택 옵션 배열로 작업하고 있습니다. 물론 필터 그룹에 선택 항목이있는 경우에만 배열 $and을 추가 할 수 있습니다.

    var query = { "$and":[{}] }; 
    

    을 그리고 자체에 각 필터 그룹의 조사 각 옵션에 추가 :

    그래서 다음과 같이 기본 $and 시작

    var inner = { "tags": { "$in": [] } }; 
    inner.tags["$in"].push(item); 
    

    그리고 다음에 추가 기본 검색어 :

    query["$and"].push(inner); 
    

    각 항목에 대해 린스하고 반복하십시오. 그리고 기본 쿼리 그냥 모든 필터링되지 않은 선택하기 때문에이 완벽하게 유효하며,이 또한 추가 로직을 구성하지 않고 유효합니다

    db.collection.find({ "$and": [ 
        { }, 
        { "tags": { "$in": [ "@Movie" ] } }, 
        { "tags": { "$in": [ "!R", "!PG" ] } }, 
        { "tags": { "$in": [ "#free" ] } 
    ]) 
    

    그래서 정말 MongoDB를 그것을 이해로 쿼리의 제휴로 내려 온다. 이것은 실제로 데이터 구조를 구축하는 데있어 단순한 JavaScript 배열 조작입니다. 모든 MongoDB 쿼리가 실제로 무엇입니까.

    +0

    위대한 - 그 부분적으로 mongo 기준을 구축 내 문제를 해결합니다. 나는 여전히 모든 필터 범주를 반복하고 최소 하나만 검사 된 항목에 대한 기준을 삽입해야합니다. 또한 실제로 별도의 컬렉션에 태그를 저장하고 있습니다. –