WSL2とVS Codeの準備覚え書き

Windowsの再インストールや複数台セットアップ時に
WSL2(Windows Subsystem for Linux)とVS Code(VisualStudio Code)で、
最低限の作業ができるようになる以前の準備を都度調べなくてもいいようメモとしてまとめます。

対象環境は、Windows10です。

WSL2の有効化。

Windows Subsystem for Linux (WSL) を Windows 10 にインストールする | Microsoft Docs
https://docs.microsoft.com/ja-jp/windows/wsl/install-win10

MS提供のドキュメント通りにすれば問題なし。

MS StoreからUbuntu, Windows Terminalのダウンロード。

Ubuntu 20.04 LTS
https://www.microsoft.com/store/apps/9n6svws3rx71

Windows Terminal を入手 – Microsoft Store ja-JP
https://www.microsoft.com/ja-jp/p/windows-terminal/9n0dx20hk701

Ubuntuである必要はありません。
ここでは省略しますが、併用も簡単。

Windows Terminal のテーマカラー。

Windows Terminal Color Schemes | Microsoft Docs
https://docs.microsoft.com/ja-jp/windows/wsl/user-support

個人的に “One Half Dark” を選択。

Windows ターミナルのすりグラステーマ
Windows ターミナルすりグラステーマの構成 | Microsoft Docs

何故かターミナルは透過設定したくなりがち。

VS Codeのインストール。

Visual Studio Code – Code Editing. Redefined
https://code.visualstudio.com/

VS Code拡張機能Remote SSHを追加

VS Code内Ctrl + Shift + Xから “Remote SSH” で検索。
色々面倒な場合は “Remote Development” で色々一括で入る(教えてもらった)

WSL2からWindowsディレクトリの参照。

C:ドライブ直下を参照する場合

$ ls -l mnt/c/

おわり。

ここから更にVS Codeの拡張を入れたり、
Dockerやgit、npm等を必要に応じてインストールしていきますが、
ひとまず作業に取り掛かろうという空気はそこはかとなく出せる状態になったはず。

VMでLinuxの環境を作るよりもお手軽かつ高速で、
改めてWindowsで環境を準備するのも楽になったと感じます。

諸々の事情によりVMの環境も欲しくなりますが…。

ここまでご覧いただきありがとうございます。

【Solr】Result Grouping と Facet との組み合わせ

前回取り上げた Result Grouping は Facet と組み合わせることができます。大阪の施設情報の例で言うと、type フィールドでファセットを作り、それぞれに含まれる area フィールドのグループの件数を求め る、といったことができます。

ただし、分散検索においては同じグループに属するドキュメントは同じシャードに置かれなければならない、という制限があります。

特定の条件に当てはまるドキュメントを同じシャードに配置するためにはドキュメントIDに複合キーを指定します。具体的には以下のような形になります。

通常
{"id":"10","type":"官公庁","area":"住之江区","name":"軽自動車検査協会大阪主管事務所","address":"住之江区南港東3-4-62","address_p":"34.6164938333333,135.438210722222"}
areaフィールドの値が同じドキュメントを同じシャードに配置
{"id":"住之江区!10","type":"官公庁","area":"住之江区","name":"軽自動車検査協会大阪主管事務所","address":"住之江区南港東3-4-62","address_p":"34.6164938333333,135.438210722222"}

idの値を “areaの値!本来のid” とすることでareaの値が同じドキュメントが同じシャードでインデックスされます。

組み合わせを試す前に、 まずは type フィールドを使った通常の Facet 検索の結果です。

$ curl -s 'http://localhost:8983/solr/osaka_shisetsu2/select?q=*:*&rows=0&facet=on&facet.field=type_str'
{
  "responseHeader":{
    "zkConnected":true,
    "status":0,
    "QTime":2,
    "params":{
      "q":"*:*",
      "facet.field":"type_str",
      "rows":"0",
      "facet":"on"}},
  "response":{"numFound":9238,"start":0,"maxScore":1.0,"numFoundExact":true,"docs":[]
  },
  "facet_counts":{
    "facet_queries":{},
    "facet_fields":{
      "type_str":[
        "駅・バス停",2574,
        "公園・スポーツ",1090,
        "駐車場・駐輪場",1049,
        "学校・保育所",1045,
        "医療・福祉",840,
        "会館・ホール",642,
        "名所・旧跡",561,
        "警察・消防",330,
        "公衆トイレ",322,
        "官公庁",301,
        "文化・観光",290,
        "その他",141,
        "環境・リサイクル",53]},
    "facet_ranges":{},
    "facet_intervals":{},
    "facet_heatmaps":{}}}

それぞれの件数は Facet 内のドキュメントの件数を示しています。

次にグループ検索と Facet 検索の組み合わせです。

$ curl -s 'http://localhost:8983/solr/osaka_shisetsu2/select?q=*:*&group=true&group.field=area_str&rows=0&group.facet=true&facet=on&facet.field=type_str'
{
  "responseHeader":{
    "zkConnected":true,
    "status":0,
    "QTime":4,
    "params":{
      "q":"*:*",
      "facet.field":"type_str",
      "group.facet":"true",
      "rows":"0",
      "facet":"on",
      "group.field":"area_str",
      "group":"true"}},
  "grouped":{
    "area_str":{
      "matches":9238,
      "groups":[]}},
  "facet_counts":{
    "facet_queries":{},
    "facet_fields":{
      "type_str":[
        "公園・スポーツ",25,
        "公衆トイレ",25,
        "医療・福祉",25,
        "名所・旧跡",25,
        "学校・保育所",25,
        "官公庁",25,
        "文化・観光",25,
        "駅・バス停",25,
        "その他",24,
        "会館・ホール",24,
        "警察・消防",24,
        "駐車場・駐輪場",24,
        "環境・リサイクル",20]},
    "facet_ranges":{},
    "facet_intervals":{},
    "facet_heatmaps":{}}}

それぞれの件数はグループ数(Facet に含まれるエリアの種類)です。公共の施設なのでほとんどのタイプはほとんどの区に存在している(大阪24区+「大阪市以外」というタイプがあるためほとんどのグループ数は25になっている)ためあまりおもしろい結果ではありませんが、通常の Facet 検索との違いは良く分かると思います。

ちなみに、ドキュメントルーティングの設定をせずに作ったインデックスでの同じクエリの結果は以下の通りです。

$ curl -s 'http://localhost:8983/solr/osaka_shisetsu2/select?q=*:*&group=true&group.field=area_str&rows=0&group.facet=true&facet=on&facet.field=type_str'
{
  "responseHeader":{
    "zkConnected":true,
    "status":0,
    "QTime":7,
    "params":{
      "q":"*:*",
      "facet.field":"type_str",
      "group.limit":"3",
      "group.facet":"true",
      "rows":"0",
      "facet":"on",
      "group.field":"area_str",
      "group":"true"}},
  "grouped":{
    "area_str":{
      "matches":9238,
      "groups":[]}},
  "facet_counts":{
    "facet_queries":{},
    "facet_fields":{
      "type_str":[
        "医療・福祉",50,
        "学校・保育所",50,
        "官公庁",50,
        "駅・バス停",50,
        "公衆トイレ",49,
        "名所・旧跡",49,
        "会館・ホール",48,
        "公園・スポーツ",48,
        "駐車場・駐輪場",48,
        "警察・消防",47,
        "文化・観光",46,
        "その他",40,
        "環境・リサイクル",29]},
    "facet_ranges":{},
    "facet_intervals":{},
    "facet_heatmaps":{}}}

2つのシャードそれぞれでグループ化が実行されるため、重複が発生してグループの数が倍近くになってしまいます。これを防ぐために複合キーを用いたドキュメントルーティングが必要になる訳です。

そうだxcoinで金を買おう

前回、文化人・著作家&ラーメン屋である竹田恒泰氏の運営するステーブルコインサービス「xcoin」を紹介させていただきました。
前年5月15日にローンチしたxcoin。もうすぐ1年を迎える中で色々パワーアップしているので新しい動向をお伝えできればと思います!

なお、xcoinやステーブルコインについては詳しくは前回の記事をご覧ください。

パワーアップしたxcoin!

xcoin-gold

なんと金・銀・プラチナの取り扱いを開始!!
xcoinに現金をチャージしておけばいつでも金・銀・プラチナをワンタップで換金できてしまうわけなのです(興奮)!!私も1万5000円分ぐらいをゴールドに交換。2グラム所有してますw

ponta
そしてポンタポイントと連携開始!!
ということは実質ポンタポイントで金が購入できるようになりますwwwwww

なぜゴールドなのか!?現金をもつよりも貴金属を所有しておくのが吉??


2021年2月現在、先日テスラ社のイーロン・マスクがビットコインを購入しました。イーロン・マスクは実のところ「ビットコインだけ」を購入しているのではなく「ビットコインを含む」デジタルアセット全般を購入し、かつ「金」も購入しています。これの意味するところはインフレリスクの対策です。

コロナによる経済対策で世界中で貨幣がジャブジャブ量産され、実質世界経済の中心であるアメリカでも総額200兆円規模の大型追加経済対策が発表されました。これだけ市場に貨幣が溢れるとインフレのリスクも相対的に大きくなります。だから世の中のお金持ちは貨幣を金やデジタルアセット等に換えていっているわけですね。

アメリカの大きすぎる経済対策が抱える不安 / 東洋経済ONLINE

今後必然的にゴールドの価値は伸びていくでしょうし、燃料電池の触媒に必要不可欠であるプラチナも間違いなく高騰すると竹田氏は睨んでいます。

脱炭素、水素社会がプラチナを押し上げる?! [ひろこの番組後記]

余談になりますが、ビットコインの爆上がりを受けマイニング用途のGPUも値上がりしており、NVIDAのGeForce RTX3060は品薄状態らしいです…GTX1060の再来ですね…

xcoinのコモディティ化対策にもなっている

いよいよ各国が正式にデジタル通貨発行への取り組みを発表しており、日本でも21年度の早い時期に市場導入実験を計画していたりしており、今年はデジタル通貨元年になる可能性もあります。

日銀がデジタル通貨実験 「21年度の早い時期に」/ 日経デジタル

国が動き出したらイチ企業のサービスは飲み込まれる恐れがあります。そこでベンチャーの足回りを活かしてxcoin内でデジタル通貨以外のものを早々に購入可能にした。動きの遅い国営サービスとは一歩も二歩もリードしていく。そんな気概を感じられますね!

xcoinはもうすぐxcoinダイヤモンドをローンチする予定で、さらには銅や先物取引にも利用できるように計画中だとか。


まだxcoin自体での現物購入はラーメンしか購入できませんがwwwwww
聞くところによるとURで住宅を借りているとポンタポイントが貯まるようなのでURにお住まいの方はxcoinはやり得ですね。
今後もxcoinは目が離せません!!

【Solr】検索結果のグループ化(Result Grouping)

はじめに

Solr には Result Grouping という機能があり、検索結果を何らかの条件でグループ化できます。Solr リファレンスガイドで挙げられている例が Result Grouping の動作を知るにはいまいちな感じだったので、別のドキュメントを使って試してみました。

準備

サンプルとして大阪の施設情報を利用します。

デフォルトの configset でコレクション osaka_shisetsu を作成し、施設情報のデータを投入します。

$ cd server/solr/configsets
$ cp -r _default osaka_shisetsu
$ ../../scripts/cloud-scripts/zkcli.sh -zkhost localhost:9983 -cmd upconfig -confdir osaka_shisetsu/conf -confname osaka_shisetsu
$ curl -s 'http://localhost:8983/solr/admin/collections?action=CREATE&name=osaka_shisetsu&numShards=2&maxShardsPerNode=2&replicationFactor=2&collection.configName=osaka_shisetsu'
$ curl 'http://localhost:8983/solr/osaka_shisetsu/update?commit=true&indent=true' --data-binary @/tmp/data.json -H 'Content-Type: application/json'
$ curl -s 'http://localhost:8983/solr/osaka_shisetsu/select?q=*%3A*&rows=2'
{
  "responseHeader":{
    "zkConnected":true,
    "status":0,
    "QTime":15,
    "params":{
      "q":"*:*",
      "rows":"2"}},
  "response":{"numFound":9238,"start":0,"maxScore":1.0,"numFoundExact":true,"docs":[
      {
        "id":"10",
        "type":["官公庁"],
        "area":["住之江区"],
	"name":["軽自動車検査協会大阪主管事務所"],
        "address":["住之江区南港東3-4-62"],
        "address_p":"34.6164938333333,135.438210722222",
	"_version_":1692768899944153088},
      {
        "id":"11",
        "type":["官公庁"],
	"area":["住之江区"],
        "name":["大阪陸運支局なにわ自動車検査登録事務所"],
        "address":["住之江区南港東3-1-14"],
        "address_p":"34.6190439722222,135.442191833333",
	"_version_":1692768899950444544}]
  }}

グルーピング検索

施設名に「事務所」を含むものをエリアでグループ化する検索を実行します。

$ curl -s 'http://localhost:8983/solr/osaka_shisetsu/select?group.field=area_str&group=true&q=name%3A%E4%BA%8B%E5%8B%99%E6%89%80'
{
  "responseHeader":{
    "zkConnected":true,
    "status":500,
    "QTime":12,
    "params":{
      "q":"name:事務所",
      "group.field":"area_str",
      "group":"true"}},
  "error":{
    "metadata":[
      "error-class","org.apache.solr.common.SolrException",
      "root-error-class","org.apache.solr.client.solrj.impl.BaseHttpSolrClient$RemoteSolrException"],
    "msg":"org.apache.solr.client.solrj.SolrServerException: No live SolrServers available to handle this request:[http://127.0.1.1:8983/solr/osaka_shisetsu_shard2_replica_n6, http://127.0.1.1:7574/solr/osaka_shisetsu_shard2_replica_n4, http://127.0.1.1:8983/solr/osaka_shisetsu_shard1_replica_n2]",
(略)
    "code":500}}

500エラーになってしまいました。

solr.log のエラーメッセージから、グループ化の対象のフィールドが multi-valued となっているのが原因であることが分かりました。

2021-02-26 13:59:29.828 ERROR (qtp691691381-15) [c:osaka_shisetsu s:shard2 r:core_node7 x:osaka_shisetsu_shard2_replica_n4] o.a.s.h.RequestHandlerBase java.lang.IllegalStateException: unexpected docvalues type SORTED_SET for field 'area_str' (expected=SORTED). Re-index with correct docvalues type.
    at org.apache.lucene.index.DocValues.checkField(DocValues.java:317)
    at org.apache.lucene.index.DocValues.getSorted(DocValues.java:369)
    at org.apache.lucene.search.grouping.TermGroupSelector.setNextReader(TermGroupSelector.java:57)
    at org.apache.lucene.search.grouping.FirstPassGroupingCollector.doSetNextReader(FirstPassGroupingCollector.java:349)

リファレンスにも確かに single-valued で indexed なフィールドでないといけないと書かれていました。

group.field
The name of the field by which to group results. The field must be single-valued, and either be indexed or a field type that has a value source and works in a function query, such as ExternalFileField. It must also be a string-based field, such as StrField or TextField

そこで、ダイナミックフィールド *_str の定義を multi-valued な strings 型から single-valued な string 型に変更してインデックスを作り直しました。

<fieldType name="string" class="solr.StrField" sortMissingLast="true" docValues="true" />
<fieldType name="strings" class="solr.StrField" sortMissingLast="true" multiValued="true" docValues="true" />

<dynamicField name="*_str" type="strings" stored="false" docValues="true" indexed="false" useDocValuesAsStored="false"/>

改めて検索を実行します。

$ curl -s 'http://localhost:8983/solr/osaka_shisetsu/select?group.field=area_str&group=true&rows=3&q=name%3A%E4%BA%8B%E5%8B%99%E6%89%80'
{
  "responseHeader":{
    "zkConnected":true,
    "status":0,
    "QTime":27,
    "params":{
      "q":"name:事務所",
      "rows":"3",
      "group.field":"area_str",
      "group":"true"}},
  "grouped":{
    "area_str":{
      "matches":685,
      "groups":[{
          "groupValue":"浪速区",
          "doclist":{"numFound":6,"start":0,"maxScore":5.533971,"numFoundExact":true,"docs":[
              {
                "id":"23",
                "type":["官公庁"],
                "area":["浪速区"],
                "name":["難波年金事務所"],
                "address":["浪速区敷津東1-6-16"],
                "address_p":"34.6588191388888,135.49922225",
                "_version_":1692817725524541443}]
          }},
        {
          "groupValue":"西区",
          "doclist":{"numFound":15,"start":0,"maxScore":5.533971,"numFoundExact":true,"docs":[
              {
                "id":"37",
                "type":["官公庁"],
                "area":["西区"],
                "name":["堀江年金事務所"],
                "address":["西区北堀江3-10-1"],
                "address_p":"34.6750045555555,135.488194555555",
                "_version_":1692817725525590019}]
          }},
        {
          "groupValue":"東成区",
          "doclist":{"numFound":13,"start":0,"maxScore":5.533971,"numFoundExact":true,"docs":[
              {
                "id":"78",
                "type":["官公庁"],
                "area":["東成区"],
                "name":["今里年金事務所"],
                "address":["東成区大今里西2丁目1番8号"],
                "address_p":"34.6714081388888,135.539616805555",
                "_version_":1692817725528735750}]
          }}]}}}

名前に「事務所」を含む施設がエリア名でグループ化されて、それぞれのグループの検索結果が6件、15件、13件であることが分かります。

rows を指定することでグループ数を、group.limit を指定することでグループ毎のドキュメントの件数を変更できます。

$ curl -s 'http://localhost:8983/solr/osaka_shisetsu/select?group.field=area_str&group=true&rows=2&group.limit=3&q=name%3A%E4%BA%8B%E5%8B%99%E6%89%80'
{
  "responseHeader":{
    "zkConnected":true,
    "status":0,
    "QTime":30,
    "params":{
      "q":"name:事務所",
      "group.limit":"3",
      "rows":"2",
      "group.field":"area_str",
      "group":"true"}},
  "grouped":{
    "area_str":{
      "matches":685,
      "groups":[{
          "groupValue":"浪速区",
          "doclist":{"numFound":6,"start":0,"maxScore":5.533971,"numFoundExact":true,"docs":[
              {
                "id":"23",
                "type":["官公庁"],
                "area":["浪速区"],
                "name":["難波年金事務所"],
                "address":["浪速区敷津東1-6-16"],
                "address_p":"34.6588191388888,135.49922225",
                "_version_":1692817725524541443},
              {
                "id":"552",
                "type":["学校・保育所"],
                "area":["浪速区"],
                "name":["大阪市立広田保育所"],
                "address":["浪速区日本橋西2-8-11"],
                "address_p":"34.6561468333333,135.50211125",
                "_version_":1692817725561241605},
              {
                "id":"3653",
                "type":["警察・消防"],
                "area":["浪速区"],
                "name":["浪速消防署立葉出張所"],
                "address":["浪速区桜川2-14-12"],
                "address_p":"34.6636563055555,135.489044111111",
                "_version_":1692817725818142729}]
          }},
        {
          "groupValue":"西区",
          "doclist":{"numFound":15,"start":0,"maxScore":5.533971,"numFoundExact":true,"docs":[
              {
                "id":"37",
                "type":["官公庁"],
                "area":["西区"],
                "name":["堀江年金事務所"],
                "address":["西区北堀江3-10-1"],
                "address_p":"34.6750045555555,135.488194555555",
                "_version_":1692817725525590019},
              {
                "id":"200",
                "type":["官公庁"],
                "area":["西区"],
                "name":["環境局河川事務所"],
                "address":["西区新町4-20-3"],
                "address_p":"34.6778531944444,135.483258083333",
                "_version_":1692817725531881486},
              {
                "id":"95",
                "type":["官公庁"],
                "area":["西区"],
                "name":["なにわ西府税事務所"],
                "address":["西区本田1-6-16"],
                "address_p":"34.6784530277777,135.479935888888",
                "_version_":1692817725529784322}]
          }}]}}}

梅酒を作る

今年も梅酒の季節が来ました。
多分出来合いのものを買ったほうが安いしおいしいと思うのですが、自己満足で作るようにしてます。

材料

  • 南高梅1kg
  • 氷砂糖700g前後
  • ホワイトリカー1.8リットル
  • 容器(4リットル)

材料は毎年だいたい5月末から6月にスーパーで果実酒コーナーが作られて全部まとめて用意されています。

ちなみになぜ氷砂糖なのか調べてみたところ、浸透圧を利用するためだそうです。

  1. 作りたては梅の実が一番濃い状態
  2. 浸透圧により梅の実に水分が移動する
  3. 時間とともに氷砂糖がゆっくりと溶け出し、梅の実よりも外のほうが濃い状態になる
  4. 浸透圧により梅の実から水分が外に移動する。この時に梅エキスも一緒に出ていく

作り方

  1. 容器の洗浄と消毒
    容器によっては熱湯消毒をすると割れてしまうので気をつけてください。
  2. 水洗い
  3. 水分を拭き取り乾かす
  4. ヘタをとる
  5. 容器へ入れる
    なるべく梅と氷砂糖が交互になるように
  6. ホワイトリカーを入れる
  7. しっかりとフタを締めて冷暗所へ

だいたい半年くらいから飲めるようです。
2年目が一番好まれているとかなんとか
手軽にできる割に満足感が高いのでぜひお試しください。

※飲酒は20歳になってから
※飲酒運転は法律で禁止されています。
※アルコール度数が低いものを使ったり自分が楽しむ目的でない場合、酒税法違反となる場合があります。