2017-03-28 10 views
0

私は映画/テレビのタイトルを格納するための基本的なcrudアプリケーションを構築しています。プロジェクト管理者がこのバージョンを選択したので、私はelasticsearchのバージョン2.4.4を使用しています。私はネイティブなelasticsearch nodejsドライバと一緒にエクスプレスフレームワークを使用しています。ドキュメントのフィールドを動的に更新するにはどうすればよいですか?

現在のところ、これは私のマッピングが "title"タイプの "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をサポートしています。

:このように、代わりに

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" 
     }); 
    }); 
}; 

をあなたはisDeletedフラグがfalseの場合のみ、ドキュメントを更新する必要がある場合は、あなたが同じAPI呼び出しを使用することができますが、スクリプトを使って:あなたは代わりにupdate callを使用する必要があります

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" 
     }); 
    }); 
}; 

この2番目の方法を使用する場合は、elasticsearch.yml設定ファイルにenable dynamic scriptingが必要です。

+0

これは機能します。どうもありがとうございます! :)あなたはスクリプトのための方向に私を指すことができますか?私はメソッドがあることを知らなかった.putall – Nate

+0

'ctx._source'はJavaマップであるソースドキュメントを参照するので、Groovyでは' putAll'メソッドを使うことができます。 – Val

+0

ごめんなさい、お手伝いできますか?あなたの方法を試してみると、エラーが発生します。エラー:[remote_transport_exception] [Agon] [127.0.0.1:9300] [インデックス:データ/書き込み/更新] – Nate

関連する問題