F# を使って雑にExcelから取り出したデータをElasticsearchに放り込む
この記事はF# Advent Calendar 2017の25日目の記事です。 大遅刻しましたごめんなさい…。
とあるExcelファイルがでかすぎて閲覧するのに苦痛だったので書きなぐった時のメモ。 .NET Coreです。
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp2.0</TargetFramework> </PropertyGroup> <ItemGroup> <Compile Include="Program.fs" /> </ItemGroup> <ItemGroup> <PackageReference Include="EPPlus" Version="4.5.0.1-beta" /> <PackageReference Include="Nest" Version="5.6.0" /> </ItemGroup> </Project>
まだbeta段階ですがEPPlusもnetstandard版があります。
open System open System.IO open OfficeOpenXml open Nest let getSheet (sheet: string) (excel: ExcelPackage) = excel.Workbook.Worksheets.[sheet] type Questionnaire = { Value: string } let getQuestionnaire (excel: ExcelPackage) = let sheet = getSheet "アンケート" excel seq { for i in [ 2 .. Seq.length sheet.Cells - 1] -> { Value = sheet.Cells.[i, 1].Text } } let questionnairesIndex = IndexName.op_Implicit "questionnaires" let createIndex (name: IndexName) (client: ElasticClient) = client.CreateIndex(name) |> ignore let insertQuestionnaire (client: ElasticClient) (messages: Questionnaire seq) = client.IndexMany(messages, questionnairesIndex, TypeName.op_Implicit "questionnaire") |> ignore [<EntryPoint>] let main argv = let file = argv.[0] let url = argv.[1] let user = argv.[2] let pass = argv.[3] use excel = new ExcelPackage(File.OpenRead(file)) printfn "try to connect %s" url use settings = (new ConnectionSettings(Uri(url))) .BasicAuthentication(user, pass) .DisableDirectStreaming() let client = ElasticClient(settings) createIndex questionnairesIndex client getQuestionnaire excel |> insertQuestionnaire client 0
仕様だったりCellにheaderが付いていた関係だったりでindexが少々ずれていますが気にしないでください。 雑に取得してdockerで立ち上げたElasticsearchに放り込むくらいだったらこれで十分ですはい。
とはいえElasticsearch 6.0系からmulti typeが廃止されたという事実に気づかずどハマりしましたが…。