我们正在使用Nutch抓取一些网站,将索引推送到Elasticsearch并使用自定义UI通过调用Elasticsearch API进行搜索。
问题是我需要抓取一些网站但将它们从Elasticsearch索引中排除(例如,我需要抓取A,B和C,但是从索引中排除B)我们不能找到我们可以在推送索引到Elasticsearch阶段期间实现的解决方案,因此我们决定尝试过滤Elasticsearch查询页面。
elasticsearch索引(由nutch创建)包含一个URL字段。这是完美的,但问题是Elasticsearch(据我所知)使用全文方法解析了这一点,例如http://bheliom.github.io/Satellite-tracking/实际上被解析为4个或更多键盘(http,www,somesite,com)。我无法弄清楚如何构建一个Elasticsearch查询,例如,排除这些URL:
http://www.somesite.com/contact/
当我运行我的DSL查询时,似乎它正在分解它(我的意思是http,www,somesite,com)并将它们组合在一起,它们总是返回所有结果。
例如:
{
"query": {
"must": { "match": { "url": "http://www.somesite.com/page1" }}
}
}
始终返回所有结果。
有人做过这样的事吗?
答案 0 :(得分:0)
对于正则表达式尝试 -
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html
您可以将网址标记为关键字,只需对其进行术语查询,或者不通过在映射中设置not_analysed来分析此字段。
关键字标记符 -
https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-keyword-tokenizer.html
了解not_analysed here-
https://www.elastic.co/guide/en/elasticsearch/guide/current/mapping-intro.html
但是,如果您想基于域和路径进行过滤,请在应用程序级别更好地分离主机和路径,然后单独编制索引。
答案 1 :(得分:0)
您还没有指定您正在使用哪个版本的Nutch。在Nutch方面有两种方法可以完成相同的操作(不考虑你的后端Solr / ES)。
一个选项是您可以在IndexingFilter
方法中实现自己的filter
(https://github.com/apache/nutch/blob/master/src/java/org/apache/nutch/indexer/IndexingFilter.java#L55-L56),如果您返回null,文档将被丢弃(即未编入索引),所以在您的实现您可以拥有自己的逻辑(比如匹配URL的主机名)并拒绝那些您不想索引的文档。
在Nutch v1.14中添加了一种新的通用方法,添加了一个支持通用JEXL表达式(https://commons.apache.org/proper/commons-jexl/reference/syntax.html)的新IndexingFilter
,因此您可以排除一些匹配a的文档具体情况。这种方法的优点是您不需要编写任何代码。 缺点是现在的URL。实际上,如果您使用hostname
无法进行过滤,但您可以使用带有正则表达式index-basic
过滤器,那么主机名应该在JEXL上下文中的doc.host
键下可用。
至于问题的ES方面,默认情况下,Nutch在向ES发送文档时不会强制执行任何映射。这意味着ES将尝试查看每个字段的内容,然后确定最佳可能的映射。例如,在这种情况下,我认为将url
字段映射为通用文本字段(实际上将内容拆分为标记)。
一个解决方案可能是在将文档发送到ES(在Nutch上编制索引)之前,您可以手动为那些您知道所需类型的字段创建映射,例如url
作为字符串/关键字。请记住,只要您没有设置冲突的映射,这不应该导致Nutch出现任何问题,但通常将所有内容设置为字符串/关键字并查看创建的字段足以定义您自己的映射。
但是如果您只想在编制索引之前过滤内容,那么其他两种解决方案可能是最好的方法。