日付の書式設定と日付演算

日付の書式設定

Solrの日付フィールド (DatePointFieldDateRangeField、および非推奨のTrieDateField) は、「日付」をミリ秒精度の時点として表します。使用される形式は、XML Schema仕様のdateTimeの正規表現の制限された形式であり、ISO-8601の制限されたサブセットです。Javaの日付処理に詳しい方のために説明すると、Solrは書式設定にDateTimeFormatter.ISO_INSTANTを使用しており、解析も「寛容さ」を伴います。

YYYY-MM-DDThh:mm:ssZ

  • YYYYは年です。

  • MMは月です。

  • DDは月の日です。

  • hhは24時間制の時刻です。

  • mmは分です。

  • ssは秒です。

  • Zは、この日付の文字列表現がUTCであることを示すリテラルの「Z」文字です。

タイムゾーンは指定できないことに注意してください。日付の文字列表現は常に協定世界時(UTC)で表されます。以下に値の例を示します。

1972-05-20T17:33:18Z

必要に応じて秒の小数部を含めることもできますが、ミリ秒を超える精度は無視されます。以下に秒の小数部を含む値の例を示します。

  • 1972-05-20T17:33:18.772Z

  • 1972-05-20T17:33:18.77Z

  • 1972-05-20T17:33:18.7Z

0000年より前の日付には先頭に「-」を付ける必要があり、Solrは9999年以降の年は先頭に「+」を付けて日付をフォーマットします。0000年は紀元前1年と見なされます。西暦0年や紀元前0年のようなものはありません。

クエリのエスケープが必要な場合があります

ご覧のとおり、日付形式には、時間、分、秒を区切るコロン文字が含まれています。コロンはSolrの最も一般的なクエリパーサーにとって特別な文字であるため、正確に何をしようとしているかによっては、エスケープが必要になる場合があります。

これは通常、無効なクエリです:datefield:1972-05-20T17:33:18.772Z

これらは有効なクエリです
datefield:1972-05-20T17\:33\:18.772Z
datefield:"1972-05-20T17:33:18.772Z"
datefield:[1972-05-20T17:33:18.772Z TO *]

日付範囲の書式設定

SolrのDateRangeFieldは、上記で説明した同じ時点の日付構文(以下で説明する日付演算を含む)と、日付範囲を表すためのさらに多くの構文をサポートしています。例の1つは、指定された精度までの日付全体のスパンを表す切り捨てられた日付です。もう1つのクラスは、範囲構文 ([ TO ]) を使用します。以下にいくつかの例を示します。

  • 2000-11 – 2000年11月全体。

  • 1605-11-05 – 11月5日。

  • 2000-11-05T13 – 同様に、1日の1時間(1300から1400前、つまり午後1時から午後2時)。

  • -0009 – 紀元前10年。年位置の0は西暦0年であり、紀元前1年とも見なされます。

  • [2000-11-01 TO 2014-12-01] – 日分解能での指定された日付範囲。

  • [2014 TO 2014-12-01] – 2014年の初めから12月1日の終わりまで。

  • [* TO 2014-12-01] – 表現可能な最も早い時間から2014-12-01の終わりまで。

制限事項:範囲構文は埋め込みの日付演算をサポートしていません。NOW/DAYのように、日付演算で切り捨てるDatePointFieldでサポートされている日付インスタンスを指定した場合、その日の範囲全体ではなく、その日の最初のミリ秒が取得されます。排他的な範囲 ({ & }を使用) はクエリでは機能しますが、インデックス作成の範囲では機能しません。

日付演算

Solrの日付型フィールドは、日付演算式もサポートしており、固定された時点からの相対的な時刻を簡単に作成できます。これには、特別な値 "NOW" を使用して表現できる現在時刻も含まれます。

日付演算の構文

日付演算式は、指定された単位で時間の量を加算するか、指定された単位で現在時刻を丸めることで構成されます。式は連鎖させることができ、左から右に評価されます。

例:これは、現在から2ヶ月後の時点を表します。

NOW+2MONTHS

これは1日前を表します。

NOW-1DAY

スラッシュは、丸めを示すために使用されます。これは、現在の時間の始まりを表します。

NOW/HOUR

次の例では、(ミリ秒精度で)現在から6ヶ月と3日後の時点を計算し、その時間をその日の始まりに丸めます。

NOW+6MONTHS+3DAYS/DAY

日付演算は、NOWに対する相対的な時間として最も一般的に使用されますが、任意の固定された時点にも適用できることに注意してください。

1972-05-20T17:33:18.772Z+6MONTHS+3DAYS/DAY

日付演算の単位オプション

次の単位は、日付演算式で使用できます。最初の列はSolrの日付演算式で使用される値です。2番目の列は、時間の単位に対して複数のエイリアスが存在するため、対応する時間単位です。

日付演算式の単位 時間単位

YEAR

YEARS

MONTH

ヶ月

MONTHS

ヶ月

DAY

DAYS

DATE

HOUR

時間

HOURS

時間

MINUTE

MINUTES

SECOND

SECONDS

MILLI

ミリ秒

MILLIS

ミリ秒

MILLISECOND

ミリ秒

MILLISECONDS

ミリ秒

日付演算に影響するリクエストパラメータ

NOW

NOWパラメータは、分散リクエスト内の複数のノード間で一貫した日付演算式解析を保証するために、Solrによって内部的に使用されます。ただし、NOWの特別な値が日付演算式に影響を与えるすべての状況でオーバーライドするために、任意の時点(過去または未来)を使用するようにSolrに指示するために指定できます。

これは、エポックからのミリ秒(long型)として指定する必要があります。

q=solr&fq=start_date:[* TO NOW]&NOW=1384387200000

TZ

デフォルトでは、すべての日付演算式はUTCタイムゾーンに対して相対的に評価されますが、TZパラメータを指定して、指定されたタイムゾーンを基準にした日付ベースの加算および丸めを強制することにより、この動作をオーバーライドできます。

たとえば、次のリクエストは、現在の月を「1日ごと」にUTCを基準としてファセットするために範囲ファセットを使用します。

https://127.0.0.1:8983/solr/my_collection/select?q=*:*&facet.range=my_date_field&facet=true&facet.range.start=NOW/MONTH&facet.range.end=NOW/MONTH%2B1MONTH&facet.range.gap=%2B1DAY&wt=xml
<int name="2013-11-01T00:00:00Z">0</int>
<int name="2013-11-02T00:00:00Z">0</int>
<int name="2013-11-03T00:00:00Z">0</int>
<int name="2013-11-04T00:00:00Z">0</int>
<int name="2013-11-05T00:00:00Z">0</int>
<int name="2013-11-06T00:00:00Z">0</int>
<int name="2013-11-07T00:00:00Z">0</int>
...

一方、この例では、「日」は、該当する夏時間調整を含む、指定されたタイムゾーンに対して相対的に計算されます。

https://127.0.0.1:8983/solr/my_collection/select?q=*:*&facet.range=my_date_field&facet=true&facet.range.start=NOW/MONTH&facet.range.end=NOW/MONTH%2B1MONTH&facet.range.gap=%2B1DAY&TZ=America/Los_Angeles&wt=xml
<int name="2013-11-01T07:00:00Z">0</int>
<int name="2013-11-02T07:00:00Z">0</int>
<int name="2013-11-03T07:00:00Z">0</int>
<int name="2013-11-04T08:00:00Z">0</int>
<int name="2013-11-05T08:00:00Z">0</int>
<int name="2013-11-06T08:00:00Z">0</int>
<int name="2013-11-07T08:00:00Z">0</int>
...

DateRangeFieldの詳細

DateRangeFieldは、DatePointFieldが使用される場所のほぼそのままの代替になります。唯一の違いは、SolrのXMLまたはSolrJ応答形式では、格納されたデータがDateではなくStringとして公開されることです。このフィールドの基になるインデックスデータは少し大きくなります。特にUTCの場合、1秒以上の時間の単位に合致するクエリは、TrieDateFieldよりも高速になるはずです。

DateRangeFieldの主なポイントは、その名前が示すように、日付範囲をインデックス付けできるようにすることです。これを行うには、上記で示した形式で文字列を指定するだけです。また、インデックス付きデータとクエリ範囲の間に3つの異なる関係述語を指定できます。

  • Intersects (デフォルト)

  • Contains

  • Within

次のように、opローカルパラメーターを使用してクエリすることで述語を指定できます。

fq={!field f=dateRange op=Contains}[2013 TO 2018]

ほとんどのローカルパラメーターとは異なり、opは実際にはクエリパーサー(field)によって定義されません。この場合はDateRangeFieldというフィールドタイプによって定義されます。上記の例では、2013年から2018年までの範囲を含む(または等しい)インデックス付き範囲を持つドキュメントが見つかります。ドキュメント内の複数の重複するインデックス付き範囲は、事実上合体されます。

DateRangeFieldの使用例については、Solrのコミュニティwikiを参照してください