2017-03-28 1 views
0

저는 영화/TV 타이틀을 저장하기위한 기본적인 앱을 제작하고 있습니다. 내 프로젝트 관리자가이 버전을 선택했기 때문에 elasticsearch 버전 2.4.4를 사용하고 있습니다. 나는 네이티브 elasticsearch nodejs 드라이버와 함께 익스프레스 프레임 워크를 사용하고있다.문서의 필드를 어떻게 동적으로 업데이트합니까?

현재 내 매핑은 "제목"유형의 "titles"색인과 비슷합니다.

client.indices.create({ 
     index: "titles", 
     body: { 
     "mappings": { 
      "title": { 
      "properties": { 
       "seriesName":   { "type": "string", "index": "not_analyzed" }, 
       "seriesEpisodeNumber": { "type": "long", "index": "not_analyzed" }, 
       "seriesEpisodeTitle": { "type": "string", "index": "not_analyzed" }, 
       "isDeleted":   { "type": "boolean", "index": "not_analyzed" } 
      } 
      } 
     } 
     } 
    }). 

해당 ID로 문서를 업데이트하는 내 서버에 엔드 포인트가 있어야합니다. 이것은 내가이 엔드 포인트에 대한 지금까지 무엇을 가지고 "POST/API/제목/: titleID/updateTitleByID"

titlesController.updateTitleByID = function(req,res){ 
    const titleID = req.params.titleID; 
    es.updateByQuery({ 
    index: "titles", 
    type: "title", 
    body: { 
     query: { 
     bool: { 
      must: [{ 
      term: { 
       _id: titleID 
      }},{ 
       term: { 
       isDeleted: false 
       }}] 
     } 
     }, 
     script: { 
     inline: "ctx._source.seriesName = seriesName;ctx._source.seriesEpisodeNumber = seriesEpisodeNumber; ctx._source.seriesEpisodeTitle = seriesEpisodeTitle;", 
     params: { ...req.body } 
     } 
    }}).then(results => { 
     logger.info(results); 
     res.status(200).json({ 
     message: "OK" 
     }); 
    }).catch(err => { 
     logger.error(err); 
     res.status(500).json({ 
     error: "Internal server error" 
     }); 
    }); 
}; 

내가 달성하고자하는 내 req.body에서 얻을 무엇을 적으로 문서를 업데이트하는 것입니다. 예를 들어 요청 본문에서 seriesName I을 얻는 경우를 예로들 수 있습니다. 그것은 내가 업데이트하고 나머지는 그대로 둡니다. 이것을 어떻게 성취합니까?

편집 : 여기에 전체 스택 추적

Error: [remote_transport_exception] [Agon][127.0.0.1:9300][indices:data/write/update[s]] 
    at respond (/home/natealcedo/Projects/digitalfolks.hooq/node_modules/elasticsearch/src/lib/transport.js:289:15) 
    at checkRespForFailure (/home/natealcedo/Projects/digitalfolks.hooq/node_modules/elasticsearch/src/lib/transport.js:248:7) 
    at HttpConnector.<anonymous> (/home/natealcedo/Projects/digitalfolks.hooq/node_modules/elasticsearch/src/lib/connectors/http.js:164:7) 
    at IncomingMessage.wrapper (/home/natealcedo/Projects/digitalfolks.hooq/node_modules/lodash/lodash.js:4968:19) 
    at emitNone (events.js:91:20) 
    at IncomingMessage.emit (events.js:186:7) 
    at endReadableNT (_stream_readable.js:974:12) 
    at _combinedTickCallback (internal/process/next_tick.js:74:11) 
    at process._tickDomainCallback (internal/process/next_tick.js:122:9) 
당신은 하나의 문서를 업데이트하려면 업데이트별로 쿼리 엔드 포인트를 사용할 필요가 없습니다

답변

1

되면, Update API은 이후 충분한 이상입니다 partial updates을 지원합니다. 대신 update call를 사용해야합니다 :

다음 isDeleted 플래그가 false 인 경우에만 문서를 업데이트해야하는 경우

titlesController.updateDocByID = function(req,res){ 
    const titleID = req.params.titleID; 
    const partialFields = req.body; 
    // TODO do some validations on the received fields 
    es.update({ 
    index: "titles", 
    type: "title", 
    id: titleID, 
    body: { 
     doc: partialFields 
    }}).then(results => { 
     logger.info(results); 
     res.status(200).json({ 
     message: "OK" 
     }); 
    }).catch(err => { 
     logger.error(err); 
     res.status(500).json({ 
     error: "Internal server error" 
     }); 
    }); 
}; 

는, 당신은 동일한 API 호출을 사용할 수 있지만이 같은 대신 스크립트와

titlesController.updateDocByID = function(req,res){ 
    const titleID = req.params.titleID; 
    const partialFields = req.body; 
    // TODO do some validations on the received fields 
    es.update({ 
    index: "titles", 
    type: "title", 
    id: titleID, 
    body: { 
     script: "if (!ctx._source.isDeleted) { ctx._source.putAll(params.partialFields) }", 
     params: {partialFields: partialFields} 
    }}).then(results => { 
     logger.info(results); 
     res.status(200).json({ 
     message: "OK" 
     }); 
    }).catch(err => { 
     logger.error(err); 
     res.status(500).json({ 
     error: "Internal server error" 
     }); 
    }); 
}; 

두 번째 방법을 사용하는 경우 elasticsearch.yml 구성 파일에 enable dynamic scripting이 필요합니다.

+0

이것은 작동합니다. 정말 고맙습니다! :) 당신은 스크립팅의 방향으로 나를 지적 할 수 있습니까? – Nate

+0

'ctx._source'는 Java Map 인 소스 문서를 참조하므로 Groovy에서는'putAll' 메소드를 사용할 수 있습니다. – Val

+0

죄송합니다. 나를 도와 줄 수 있습니까? 귀하의 방법을 시도 할 때 오류가 발생합니다. 오류 : [agon] [127.0.0.1:9300] [색인 : 데이터/쓰기/업데이트] – Nate

관련 문제