Yacy 查询语言详解

YaCy 1.942 查询语法全实测:词项/短语/排除/通配的真实语义,AND/OR 与字段限定不生效的日志级澄清,yacysearch.json API 参数与返回结构,以及底层 Solr 改写机制与替代查询路径。

YacyYaCy去中心化爬虫2026/10/24

Yacy 查询语言详解

目标:完整讲清 YaCy 1.942 搜索接口的查询语法——词项、短语、排除、通配符的真实语义,布尔与字段限定语法的实际行为(含与常见误解的澄清),/yacysearch.json API 参数与返回结构,以及查询在底层嵌入式 Solr 中的改写机制。全部语法要素均在 Ubuntu 24.04 实测环境用真实索引逐条验证,Solr 层改写证据取自 DATA/LOG/yacy00.log。

一、环境信息

  • 操作系统:Ubuntu 24.04 LTS(x86_64)
  • YaCy:1.942(官方 tar 包安装于 /opt/yacy,systemd 服务 yacy.service 托管,监听 8090)
  • 索引来源:节点默认加入 freeworld P2P 网络,本地索引由 RWI 分布式索引持续汇入(安装后数小时),未执行本地爬取
  • 查询接口:/yacysearch.json(公开端点,无需认证)
  • 观测手段:curl 调用 JSON API + grep SOLR QUERY /opt/yacy/DATA/LOG/yacy00.log 观测底层改写
  • 实测时点:2026-10-24 11:32(UTC+8)

⚠️ 时点声明:节点加入 P2P 网络后,全局索引会持续汇入本地,下文所有命中数都是实测时点的瞬时值,读者复测时数值必然不同。请关注语法行为与命中数之间的相对关系,不要背绝对值。

二、前置条件

查询语法的验证依赖本地索引非空。YaCy 本地索引有两种积累方式,实测均可用:

  1. P2P 汇入(本篇实测采用):默认配置 network.unit.dht=true 下节点入网后,其他节点的索引条目经 DHT 自动分发到本地,分钟级即可产生可检索数据。检查方式:直接发起一次查询,命中数大于 0 即已具备。
  2. 本地爬取:通过管理界面 CrawlStartExpert 页面(http://<服务器IP>:8090/CrawlStartExpert.html)填写目标 URL、深度、过滤规则后提交。⚠️ 排障实录:该表单字段较多(crawlingMode/crawlingURL/crawlingDepth/crawlingDomMaxCheck/crawlingDomMaxPages/crawlingQ/indexText/crawlingstart 等十余项),本篇实测中两次用 curl 直调 POST(分别用 url= 与完整字段两种参数组合)均返回 HTTP 200 但日志 grep -c "Crawl start" 计数为 0——任务未真正入队。爬取任务的可靠入口是管理界面表单,API 直调方式在 1.942 下未复现成功,不再展开。

查询命令模板(本篇全部实测基于此模板,替换 query 值即可):

curl -sS "http://127.0.0.1:8090/yacysearch.json?query=<URL编码后的查询>&maximumRecords=2&verify=false&resource=local"

参数含义:maximumRecords 返回条数上限;verify=false 跳过结果在线验证(不对结果 URL 发起回访,纯索引检索,速度最快);resource=local 限定只搜本地索引(改 global 则向 P2P 网络转发)。

三、语法总览

YaCy 1.942 查询串的实际语义(全部经 Solr 改写日志与返回结果双重验证):

语法要素写法示例实际行为是否生效
词项yacy逐词匹配,多词之间为"应满足 N 个"的弹性匹配(edismax mm 机制)生效
短语(引号)"search engine"保留为单个短语项,整体匹配生效
排除(减号)search -decentralized-词 作为排除子句传入 Solr生效
后缀通配符craw*被截断为前缀 cra(非完整 craw*),召回范围扩大半生效(有截断陷阱)
布尔 ANDyacy AND crawlerAND 不做布尔运算,作为普通词项 and 参与匹配不生效
布尔 ORyacy OR linuxOR 作为普通词项 or 参与匹配不生效
字段限定host:yacy.net冒号被丢弃,字段名 host 与值 yacy.net 均转为普通词项不生效(无字段过滤)

总览解读:YaCy 的查询语法是面向人的自然词检索而非 Lucene 布尔语法——引号短语、减号排除、弹性词项匹配是可靠的三件套;布尔关键字与字段限定符在 JSON 接口上不产生结构化效果,这一点与很多资料的说法相反,第六章给出日志级证据。需要严格布尔/字段过滤时,应改用 /solr/select 直查内嵌 Solr(第七章)。

四、基础语法详解

4.1 词项与弹性匹配

单词与多词查询。多词时 Solr 的 edismax mm(minimum-should-match)机制决定"至少命中几个词":

curl -sS "http://127.0.0.1:8090/yacysearch.json?query=yacy&maximumRecords=2&verify=false&resource=local"
curl -sS "http://127.0.0.1:8090/yacysearch.json?query=search&maximumRecords=2&verify=false&resource=local"

实测回显(节选,命中数):

yacy   => total=529
search => total=181

多词查询 yacy AND crawler 的底层改写(日志实测):

[yacy AND crawler] &q="yacy"+"and"+"crawler"

即三个词项同时参与匹配、按 mm 规则弹性命中——这解释了下文 5.1 节布尔关键字"不生效"的根源。

4.2 短语匹配(引号)

双引号包裹的词组保持为完整短语项,不做拆词:

curl -sS "http://127.0.0.1:8090/yacysearch.json?query=%22search%20engine%22&maximumRecords=2&verify=false&resource=local"

实测回显(命中数与前两条):

"search engine" => total=151 items=[('YaCy Search Engine', 'https://hub.docker.com/u/yacy'), ('YaCy Search Engine · GitHub', 'https://github.com/yacy')]

底层改写证据(短语作为整体传入):

["search engine"] &q="search+engine"

对比单词 search(181 条)与短语 "search engine"(151 条)的命中差,短语约束真实生效。

4.3 排除语法(减号)

-词 表示从结果中排除包含该词的文档:

curl -sS "http://127.0.0.1:8090/yacysearch.json?query=search%20-decentralized&maximumRecords=2&verify=false&resource=local"

实测回显(命中数):

search -decentralized => total=172

底层改写证据(减号作为排除子句完整传入):

[search -decentralized] &q="search"+-"decentralized"

-"decentralized" 是 Solr 的标准排除子句,语法真实生效:对比 search(181 条)与 search -decentralized(172 条)。

4.4 通配符(含截断陷阱)

后缀 * 通配符不是按输入词根完整生效,实测被截断为前 3 个字符的前缀匹配:

curl -sS "http://127.0.0.1:8090/yacysearch.json?query=craw%2A&maximumRecords=2&verify=false&resource=local"

实测回显(命中数与前两条):

craw* => total=242 items=[('CRA Communities', 'https://cyberriskalliance.com/communities'), ('Torizon CRA Summit 2025 - Highlights', 'https://www.torizon.io/videos/cra-summit-2025-recap')]

底层改写证据:

[craw*] &q="cra"

解读:输入 craw* 被 YaCy 改写为前缀 cra——返回结果包含 CRA Communities 这类不含 "craw" 词根的文档。这是 YaCy 查询预处理的真实行为(词项进入 Solr 前被截断),召回范围比直觉更宽。使用通配符时要么接受该行为,要么用完整词搜索。单词 crawler 实测命中 12 条,可作为对照。

五、布尔与字段限定语义(实测澄清)

这一章是本篇的核心澄清:社区资料普遍声称 YaCy 支持 AND/OR 布尔运算与字段限定搜索,实测结论如下。

5.1 AND / OR:不产生布尔运算

curl -sS "http://127.0.0.1:8090/yacysearch.json?query=yacy%20AND%20crawler&maximumRecords=2&verify=false&resource=local"
curl -sS "http://127.0.0.1:8090/yacysearch.json?query=yacy%20OR%20linux&maximumRecords=2&verify=false&resource=local"

实测回显(命中数与前两条):

yacy AND crawler => total=344 items=[('YaCy Crawler API - YaCy', 'https://yacy.net/api/crawler/'), ('Advanced Crawler - YaCy', 'https://yacy.net/operation/crawlstart_p/')]
yacy OR linux => total=270 items=[('Research | Linux Foundation', 'https://www.linuxfoundation.org/research'), ('GitHub - smokingwheels/YaCy: Windows and Lin', 'https://github.com/smokingwheels/YaCy')]

改写证据(4.1 节):AND/OR 被转为小写词项 "and"/"or" 参与匹配。语义上是三词弹性匹配而非布尔运算——若 OR 是布尔并集,yacy OR linux 的命中数不可能小于单词 yacy 的 529 条。

5.2 字段限定(host: / url: / language: / title:):无字段过滤

四种字段前缀的实测(命中数+前两条+改写证据):

title:crawler  => total=22  items=[('Advanced Crawler - YaCy', 'https://yacy.net/operation/crawlstart_p/'), ('Solr Schema of YaCy - YaCy', 'https://yacy.net/dev/solr-schema/')]
host:yacy.net  => total=33  items=[('How to Host Overnight Guests Without a Guest...', 'https://nymag.com/strategist/article/hosting-overnight-...'), ('YaCy Crawler API - YaCy', 'https://yacy.net/api/crawler/')]
url:bot        => total=105 items=[('Community Wishlist Survey 2017/Translations/', 'https://meta.wikimedia.org/wiki/...'), ('Wikidata:Requests for permissions/Bot/TopDev', 'https://www.wikidata.org/wiki/...')]
language:de    => total=199 items=[('Choose a Language de-DE', 'https://www.apple.com/de/legal/privacy/policy/'), ('De Lucena | Encyclopedia.com', 'https://www.encyclopedia.com/religion/encyclopedias-alma')]

对应改写日志:

[host:yacy.net] &q="host"+"yacy.net"
[language:de] &q="language"+"de"
[url:bot] &q="url"+"bot"

最有力的反证是 host:yacy.net 的第一条结果来自 nymag.com(内容是"招待过夜客人",仅因含词 "host" 而命中)——冒号语法没有产生主机过滤。title:crawler 的 top 结果恰好标题相关属于巧合(这些文档同时含词 title 与 crawler),不是字段过滤的效果。

5.3 实际可用的"组合技巧"

在上述真实语义下,检索质量最高的组合是:核心词 + 短语 + 排除。例如"搜 YaCy 的爬虫文档但排除 P2P 相关":

curl -sS "http://127.0.0.1:8090/yacysearch.json?query=%22YaCy%20Crawler%22%20-p2p&maximumRecords=2&verify=false&resource=local"

语义:短语 "YaCy Crawler" 整体匹配 + 排除含 p2p 的文档。这类组合完全建立在 4.2/4.3 节验证过的机制之上,可放心使用。

六、API 参数与返回结构

6.1 /yacysearch.json 参数

参数实测值说明
query必填查询串,URL 编码;引号用 %22,空格 %20,减号原样,* 用 %2A
maximumRecords1/2/3单次返回条数上限
startRecord2结果偏移(0 基),分页翻页用
verifyfalse是否对结果 URL 在线验证;false 纯索引检索最快
resourcelocal/global检索域:仅本地 / 本地+P2P 全网转发

分页实测(startRecord=2 取第 2 条起的记录):

curl -sS "http://127.0.0.1:8090/yacysearch.json?query=yacy&maximumRecords=2&startRecord=2&verify=false&resource=local"

实测回显(节选):

startRecord=2 total: 475 items: ['https://blog.fossasia.org/tag/yacy/', 'https://github.com/Stepanov-Sergey/yacy_synonyms']

6.2 返回结构(JSON)

顶层为 channels 数组,channels[0].items 为结果条目,totalResults 为命中总数。单条结果结构(yacy AND crawler 第一条,实测原样):

{"title": "YaCy Crawler API - YaCy",
 "link": "https://yacy.net/api/crawler/",
 "description": "<b>YaCy</b> P2P - Decentralized Search Engine",
 "pubDate": "Fri, 18 Sep 2026 22:25:55 +0000",
 "size": "25130",
 "host": "yacy.net"}

字段说明:title/link/description(描述含 <b> 高亮标记)/pubDate(文档抓取时间)/size(文档字节数)/host(来源主机)。集成程序从 channels[0].totalResults 取总数、遍历 items 即可。

6.3 其他输出格式

同一查询串可用于其他输出端点。/yacysearch.rss 实测返回 RSS 2.0 XML(含 opensearch/atom/dc/media 等命名空间声明,头部节选):

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
    xmlns:yacy="http://www.yacy.net/"
    xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"
    xmlns:media="http://search.yahoo.com/mrss/"
    xmlns:atom="http://www.w3.org/2005/Atom"
    xmlns:dc="http://purl.org/dc/elements/1.1/"

RSS 适合老式订阅器对接;程序集成建议直接用 JSON 端点。

七、与 Solr 原生查询的关系

YaCy 内嵌 Solr 9,用户查询经过一层改写后交给嵌入式 Solr 执行(日志 SOLR QUERY 行完整可见)。改写机制实测要点:

  1. 查询模型:defType=edismax,字段权重表 qf=title^5.0 text_t^1.0 host_s^6.0 h1_txt^5.0 url_file_name_tokens_t^4.0 h2_txt^3.0 keywords^2.0 description_txt^1.5 author^1.0 ...(标题 5 倍、主机 6 倍权重);
  2. 固定过滤:fq=httpstatus_i:200(只返回抓取成功的文档)、fq=-content_type:(image/*)、fq=-url_file_ext_s:(jpg OR png OR gif)(排除图片类结果);
  3. 分面统计:facet.field=host_s/language_s/url_file_ext_s/author_sxt/url_protocol_s,供结果导航;
  4. 深度加权:bq=crawldepth_i:0^0.8&bq=crawldepth_i:1^0.4,越浅爬取深度权重越高;
  5. 高亮:hl=true + hl.fl=text_t,h1_txt...,描述片段的 <b> 标记由此而来。

需要严格布尔与字段过滤时的替代路径:/solr/select 端点直接接受 Solr 原生语法(如 q=title:"Crawler API"、fq=host_s:yacy.net),绕过 YaCy 的改写层。该路径属于 Solr 能力范畴(语法规则见 Apache Solr 官方文档),本篇不展开实测;日常门户与 API 集成场景,用第四章验证过的「词项+短语+排除」三件套已覆盖绝大多数需求。

八、常见问题(FAQ)

Q1:为什么 yacy AND crawler 的结果数比单词 yacy 还少(344 vs 529)? 因为 AND 不是布尔并集而是普通词项:查询实际要求文档包含 "yacy""and""crawler" 三个词中的若干个(mm 弹性规则),条件比单词更苛刻,命中数自然更少。要做"并集"效果,分两次查询在应用层合并。

Q2:host:yacy.net 为什么搜出来别的网站? 冒号字段限定在 1.942 的 JSON 接口上不生效,host 与 yacy.net 都成为普通词项(5.2 节反证实测)。需要按主机过滤时用 /solr/select 的 fq=host_s:yacy.net。

Q3:通配符搜出来的结果很多和词根无关? craw* 被截断为前缀 cra(4.4 节实测证据),召回包含 CRA/Crafter 等任何 cra 开头词。要么用完整词,要么在应用层对结果做二次过滤。

Q4:两次查询命中数不一样? 节点参与 P2P 网络时,全局索引持续经 DHT 汇入本地,索引规模分钟级增长(本篇实测窗口内 yacy 从 179 涨到 529)。对命中数敏感的程序应显式 resource=local 并缓存结果,或在 Robinson 模式(network.unit.dht=false)下运行以获得稳定索引。

Q5:verify=false 和 verify=true 有什么区别? verify=true 时 YaCy 会在返回结果前对每个候选 URL 发起在线回访验证,慢且依赖目标站可达性;verify=false 纯索引检索,毫秒级返回。API 集成一律建议 false。

九、参考链接

  1. 本篇实测环境与安装过程:《Yacy 1.942 安装指南》
  2. 配置参数(检索域/网络模式相关键):《Yacy 1.942 配置参数详解》
  3. 软件定位与架构背景:《Yacy 1.942 介绍与选型指南》
  4. Apache Solr edismax 查询语法(底层查询模型参考):https://solr.apache.org/guide/solr/latest/query-guide/edismax-query-parser.html
  5. GitHub 仓库(查询改写实现源码 source/net/yacy/search/query/):https://github.com/yacy/yacy_search_server