Solr - 计算两个日期字段范围内的文档
Solr - count documents in the range of two date fields
以下是我得到的一些示例 Solr 文档:
{
"id": "1",
"openDate": "2017-12-01T00:00:00.000Z",
"closeDate": "2017-12-04T00:00:00.000Z"
},
{
"id": "2",
"openDate": "2017-12-02T00:00:00.000Z",
"closeDate": "2017-12-04T00:00:00.000Z"
},
{
"id": "3",
"openDate": "2017-12-02T00:00:00.000Z",
"closeDate": "2017-12-06T00:00:00.000Z"
}
文档的日期 "active" 是介于 openDate(含)和 closeDate(不含)之间的日期。我想统计每天 "active" 的文档数量,所以输出应该是:
[
{
Date: 2017-12-01,
count: 1
},
{
Date: 2017-12-02,
count: 3
},
{
Date: 2017-12-03,
count: 3
},
{
Date: 2017-12-04,
count: 1
},
{
Date: 2017-12-05,
count: 1
}
]
解决这个问题的一个简单方法是保留一个多值日期字段(比如称为 openDates
),其中包含感兴趣范围内的所有日期,因此我们像这样扩展文档:
{
"id": "1",
"openDate": "2017-12-01T00:00:00.000Z",
"closeDate": "2017-12-04T00:00:00.000Z",
"openDates": ["2017-12-01T00:00:00.000Z",
"2017-12-02T00:00:00.000Z",
"2017-12-03T00:00:00.000Z"]
},
{
"id": "2",
"openDate": "2017-12-02T00:00:00.000Z",
"closeDate": "2017-12-04T00:00:00.000Z",
"openDates": ["2017-12-02T00:00:00.000Z",
"2017-12-03T00:00:00.000Z"]
},
{
"id": "3",
"openDate": "2017-12-02T00:00:00.000Z",
"closeDate": "2017-12-06T00:00:00.000Z",
"openDates": ["2017-12-02T00:00:00.000Z",
"2017-12-03T00:00:00.000Z",
"2017-12-04T00:00:00.000Z",
"2017-12-05T00:00:00.000Z"]
}
然后我可以 运行 像这样的分面查询:
/select?q=*:*&facet=true&facet.field=openDates&rows=0
获得我需要的计数。
在 Solr 中有没有更好的方法来解决这个问题?
理想情况下,替代方法可以按小时或分钟来帮助存储桶,而不仅仅是天。如果我们更细化,上述方法将有一个非常大的多值字段。另外,有没有一种好的方法可以用零计数来填补漏洞(即缺失日期)?
DateRangeField会来救援的。在架构中,您将添加如下内容:
<fieldType name="range_date" class="solr.DateRangeField" />
<field name="active" type="range_date" indexed="true" stored="false"/>
您可以像这样指定活动 range:
doc1.addField("active", "[2017-12-01T00:00:00.000Z TO 2017-12-04T00:00:00.000Z]")
以后通过此字段请求 range facets。
具有 1 天粒度的参数示例(您可以更改 gap
参数以获得不同的值):
q.add("facet", "true")
q.add("facet.range", "active")
q.add("facet.range.start", "NOW/MONTH")
q.add("facet.range.end", "NOW/MONTH+1MONTH")
q.add("facet.range.include", "outer")
q.add("facet.range.gap", "+1DAY")
我添加了 facet.range.include=outer
以保持您喜欢的精确格式响应(不包括上限和下限)。您可以通过 choosing 您想要的更多内容来更改此参数。
您将得到您所需要的:
2017-12-01T00:00:00Z
1
2017-12-02T00:00:00Z
3
2017-12-03T00:00:00Z
3
2017-12-04T00:00:00Z
1
2017-12-05T00:00:00Z
1
代码的完整示例是 here。
以下是我得到的一些示例 Solr 文档:
{
"id": "1",
"openDate": "2017-12-01T00:00:00.000Z",
"closeDate": "2017-12-04T00:00:00.000Z"
},
{
"id": "2",
"openDate": "2017-12-02T00:00:00.000Z",
"closeDate": "2017-12-04T00:00:00.000Z"
},
{
"id": "3",
"openDate": "2017-12-02T00:00:00.000Z",
"closeDate": "2017-12-06T00:00:00.000Z"
}
文档的日期 "active" 是介于 openDate(含)和 closeDate(不含)之间的日期。我想统计每天 "active" 的文档数量,所以输出应该是:
[
{
Date: 2017-12-01,
count: 1
},
{
Date: 2017-12-02,
count: 3
},
{
Date: 2017-12-03,
count: 3
},
{
Date: 2017-12-04,
count: 1
},
{
Date: 2017-12-05,
count: 1
}
]
解决这个问题的一个简单方法是保留一个多值日期字段(比如称为 openDates
),其中包含感兴趣范围内的所有日期,因此我们像这样扩展文档:
{
"id": "1",
"openDate": "2017-12-01T00:00:00.000Z",
"closeDate": "2017-12-04T00:00:00.000Z",
"openDates": ["2017-12-01T00:00:00.000Z",
"2017-12-02T00:00:00.000Z",
"2017-12-03T00:00:00.000Z"]
},
{
"id": "2",
"openDate": "2017-12-02T00:00:00.000Z",
"closeDate": "2017-12-04T00:00:00.000Z",
"openDates": ["2017-12-02T00:00:00.000Z",
"2017-12-03T00:00:00.000Z"]
},
{
"id": "3",
"openDate": "2017-12-02T00:00:00.000Z",
"closeDate": "2017-12-06T00:00:00.000Z",
"openDates": ["2017-12-02T00:00:00.000Z",
"2017-12-03T00:00:00.000Z",
"2017-12-04T00:00:00.000Z",
"2017-12-05T00:00:00.000Z"]
}
然后我可以 运行 像这样的分面查询:
/select?q=*:*&facet=true&facet.field=openDates&rows=0
获得我需要的计数。
在 Solr 中有没有更好的方法来解决这个问题?
理想情况下,替代方法可以按小时或分钟来帮助存储桶,而不仅仅是天。如果我们更细化,上述方法将有一个非常大的多值字段。另外,有没有一种好的方法可以用零计数来填补漏洞(即缺失日期)?
DateRangeField会来救援的。在架构中,您将添加如下内容:
<fieldType name="range_date" class="solr.DateRangeField" />
<field name="active" type="range_date" indexed="true" stored="false"/>
您可以像这样指定活动 range:
doc1.addField("active", "[2017-12-01T00:00:00.000Z TO 2017-12-04T00:00:00.000Z]")
以后通过此字段请求 range facets。
具有 1 天粒度的参数示例(您可以更改 gap
参数以获得不同的值):
q.add("facet", "true")
q.add("facet.range", "active")
q.add("facet.range.start", "NOW/MONTH")
q.add("facet.range.end", "NOW/MONTH+1MONTH")
q.add("facet.range.include", "outer")
q.add("facet.range.gap", "+1DAY")
我添加了 facet.range.include=outer
以保持您喜欢的精确格式响应(不包括上限和下限)。您可以通过 choosing 您想要的更多内容来更改此参数。
您将得到您所需要的:
2017-12-01T00:00:00Z
1
2017-12-02T00:00:00Z
3
2017-12-03T00:00:00Z
3
2017-12-04T00:00:00Z
1
2017-12-05T00:00:00Z
1
代码的完整示例是 here。