テーマ

Dataviewで読書ノートの一覧を作る

読んだ本を表にまとめる

2022年の読書一覧では、Dataviewを使って、書籍名、読了日、NDL請求記号を表に並べていました。

今は、こういう一覧を作るのもBasesで事足りることが増えました。

Dataviewでは、著者名から本を絞り込むこともできます。ただ、同じ名前が書いてあっても、書き方によって見つかったり、見つからなかったりします。

同じ著者名でも、文字列とリストがある

たとえば、ノートの先頭にある著者名の項目 author。YAMLでは、こんな書き方ができます。

---
author: 高野秀行
---

この場合、author に入っているのは「高野秀行」という文字列です。同じ名前でも、次の書き方だとリストになります。

---
author:
  - 高野秀行
---

author: の下に字下げして、- から始めると、名前を並べるリストになります。名前がひとつでも、文字列がひとつ入ったリストです。

見える著者名は同じですが、Dataviewにとっては別の値です。

TABLEとFROMで作る著者名の表

books というフォルダのノートから、著者名を表にまとめるクエリです。

```dataview
TABLE author
FROM "books"
```

TABLE author が表に出す項目、FROM "books" がノートを集める場所を表しています。

Dataviewプラグインが有効なら、ノートの中にあるこのコードブロックが一覧になります。最初の dataview は、ブロックの中身をDataviewのクエリとして扱うための指定です。通常のクエリなので、DataviewJSの有効化は必要ありません。

WHEREで比べているのは何か

表に出すノートを絞る条件が WHERE です。たとえば、author と「高野秀行」を = で比べると、こうなります。

TABLE author
FROM "books"
WHERE author = "高野秀行"

author: 高野秀行 と書いたノートは、この条件に一致します。一方、- 高野秀行 とリストにしたノートは一致しません。

右側の "高野秀行" は文字列です。= は左右が同じ値かどうかを比べるので、左側がリストだと、その中に「高野秀行」が入っていても一致しません。

リスト同士を = で比べることはできます。この例では、文字列とリストを比べていることが、見つからない理由です。

containsとecontainsの違い

同じ2通りの author でも、contains() なら両方が見つかります。

TABLE author
FROM "books"
WHERE contains(author, "高野秀行")

ただ、contains() では名前の一部だけでも一致します。「高野」で探しても「高野秀行」が見つかります。Dataview 0.5.70の実装では、文字列だけでなく、リストの中にある文字列も部分一致です。

リストの中に、名前が完全に一致するものがあるかを調べる関数もあります。それが econtains() です。

TABLE author
FROM "books"
WHERE econtains(author, "高野秀行")

author が著者名のリストなら、その中に「高野秀行」という名前がある場合に一致します。「高野」まで同じ、というだけでは一致しません。

文字列に対しては、econtains() も部分一致になります。つまり、文字列とリストが混在している場合は、econtains() に変えるだけでは完全一致にそろいません。

この違いは、Dataviewの関数リファレンスと0.5.70の実装で確認できます。

authorの型も表に出せる

名前だけでは分かりにくい文字列とリストの違いも、typeof() を使うと表に出せます。

TABLE author, typeof(author) AS "authorの型"
FROM "books"

このクエリには WHERE がないので、著者名による絞り込みはありません。books フォルダのノートについて、著者名と型が並びます。文字列なら string、リストなら array です。

[[高野秀行]] のように著者名をリンクで記録した場合は、また別の型になります。リンクには、ここまでの文字列の例がそのまま当てはまるわけではありません。

著者の条件をつけたときだけ本が消えるなら、名前だけでなく、この型の違いが関わっている可能性があります。条件なしでも出てこない場合は、FROM で指定したフォルダにそのノートがないことも考えられます。