2014-05-20 6 views
0

mongodb 버전 2.6.1에서 아래 쿼리를 사용하여 mongo 데이터를 필터링하려고하는데 오류가 발생합니다.

MongoDB의 버전 2.4.6 (작업)

> db.BC_1839.find({data: {$elemMatch:{$where : "this.First_name.toLowerCase().indexOf('kim') ==0"}}}); 

출력 :

{ 
    "_id" : ObjectId("53719a9d5b9e5c8c110001b9"), 
    "data" : [ 
     { 
      "First_name" : "Kimberely", 
      "Last_name" : "Weyman", 
      "Company_name" : "Scientific Agrcltl Svc Inc", 
      "Address" : "7721 Harrison St", 
      "City" : "Kingsway West", 
      "State" : "NS", 
      "Post" : "2208", 
      "Phone1" : "02-7091-8948", 
      "Phone2" : "0441-151-810", 
      "Email" : "[email protected]", 
      "Web" : "http://www.scientificagrcltlsvcinc.com.au", 
      "active" : "true" 
     } 
    ], 
    "history" : [  
     { 
      "timestamp" : "2014-05-13 06:07:55", 
      "event": "creation", 
      "createdby" : "Srikesh Infotech", 
      "creation_data" : [ 
       { 
        "crm_base_contact_id" : "1839", 
        "crm_imported_files_id" : "1464" 
       } 
      ] 
     }, 
     { 
      "timestamp" : "2014-05-13 06:09:05", 
      "event" : "Task", 
      "createdby" : "Srikesh Infotech", 
      "Task_data" : [ 
       { 
        "Campaign ID" : "193", 
        "Campagin Name" : "Test Campa1" 
       } 
      ] 
     } 
    ], 
    "ref" : [ 
     { "crm_base_contact_id" : "1839", "crm_imported_files_id" : "1464" } 
    ] 
} 

MongoDB의 버전 2.6.1 (작동하지 않음)

> db.BC_1839.find({data: {$elemMatch:{$where : "this.First_name.toLowerCase().indexOf('kim') ==0"}}}); 

출력 :

error: { 
     "$err" : "Can't canonicalize query: BadValue $elemMatch cannot contain $ 
where expression", 
     "code" : 17287 
} 

동일한 쿼리는 mongodb 버전 2.4.6에서 실행되지만 mongodb 버전 2.6.1에서는 실행되지 않습니다. 왜 ???

+0

가능한 복제본 [$ Where - Mongo PHP 코드에서 작동하지 않음] (http://stackoverflow.com/questions/23730647/where-not-working-in-mongo-php-code) –

+0

게시하지 마십시오 이전 질문에 아직 답변이 없기 때문에 동일한 질문을합니다. –

+0

다른 MongoDB 버전을 실행하지 않는 동일한 쿼리를 왜 설명 할 수 있습니까? –

답변

3

어쨌든 this의 범위를 수정하여 "데이터"를 최상위 요소로 언급 했으므로 이전 버전에서는 작동하지 않아야합니다. 요컨대, 이것은 더 이상 허용되지 않으며 절대적으로해야하는 경우가 아니면 JavaScript 메소드를 사용해서는 안됩니다. 그렇다면 대부분의 경우 여전히 더 좋은 방법이있을 것입니다.

실제로이 작업은 기존의 다른 연산자가있을 때 필요하지 않으므로 JavaScript 일치의 불필요한 사용입니다.

당신은 대신 $regex 양식을 사용한다 :

db.docs.find({ "data.First_name": /kim/i }) 

거의 자바 스크립트를 실행하지만 같은만큼 비효율적이다 :

db.docs.find({ "data.First_name": /^kim/i }) 

또는 어느 곳에서나 필드에서, 캐럿 ^를 제거 그 통역사 엔진을 통한 처리의 오버 헤드가 없기 때문입니다. 물론 모든 곳에서 사용할 수 있습니다.

은 또한 무엇을 해결하기 위해 자바 스크립트에 의존하는 쿼리가 실제로하고있는 생각 :

  • 자바 스크립트 유형에 자바 스크립트 인터프리터 인스턴스를 문서 당
  • 변환 BSON 문서 종류를 호출
  • 는에 자바 스크립트 코드를 평가 문서 당 통역자
  • 결과물 당 true|false 결과물 당

$regex (그러나 대소 문자를 구분하지 않는 일치가 최적이 아닌 경우)는 동일한 작업을 수행하지만 "pcre"C 라이브러리를 사용하여 문서 당 변환 및 재 작성없이 기본적으로 두 가지 중에서 선택의 여지가 있음을 고려하십시오.

+0

"시작하지 않는다"에 대한 정규식을 줄 수 있습니까? –

+0

@Manadh는'^'캐럿을 제거합니다. 이것이 문자열의 시작 위치에 앵커가되는 것입니다. 일반적으로 일을 더 효율적으로 만들지 만, MongoDB 색인 생성 (대소 문자 구별)은 일반 검색어를 작동시키는 방식으로 적어도 색인을 스캔하여 대소 문자를 구분하지 않는 일치를 찾아야합니다. 그러나 다른 이유로 인해 JavaScript보다 더 많은 오버 헤드가 발생하고 컬렉션 스캔이됩니다. –

+0

@Manadh 이제는 버전에 관계없이이 기능을 사용할 수 있습니까? 수락은 좋을 것이다 :) –

관련 문제