Сүрөттөө
Opensolr Search replaces WordPress’s default search with a powerful, hosted Apache Solr search engine. It combines traditional keyword search with AI-powered vector search for dramatically better relevance.
Key Features:
- Hybrid Search — combines keyword matching (BM25) with semantic vector search (1024-dim embeddings) for the best of both worlds
- Faceted Navigation — filter results by category, price range, date, custom fields, and hierarchical taxonomies
- AI Hints — streaming AI-generated answers above search results, powered by RAG
- AI Reader — full-screen AI summary of any search result
- Autocomplete — real-time search suggestions with query history and Solr results
- WooCommerce Support — index products with prices, categories, SKUs, and structured data
- Two Indexing Methods — Web Crawler (automatic) and Data Ingestion API (push from WordPress)
- Search Analytics — track queries, clicks, CTR, no-results queries, and visitor patterns
- Query Elevation — pin or exclude specific results for any query
- Persistent Filters — admin-defined include/exclude filters applied to every search
- Multilingual — automatic locale filtering for WPML and Polylang sites
- Dark Theme — built-in dark mode for the search page
- Embeddable — use native search or embed the Opensolr hosted search widget
How It Works:
- Sign up at opensolr.com and get your API key
- Install the plugin and enter your credentials
- Create a search index or connect to an existing one
- Configure your sitemap and start the web crawler
- Your search page is live at
/opensolr-search
The plugin generates a complete sitemap, injects meta tags for the crawler to extract, and provides a full search experience with zero load on your WordPress server — all search queries go directly to the Opensolr cloud.
Requirements:
- An Opensolr account (free tier available)
- PHP 8.1 or higher
- WordPress 6.0 or higher
External services
This plugin depends on several online services operated by Opensolr (https://opensolr.com) to provide hosted search. You must have an Opensolr account; all indexing and search queries flow through these services. The service is required for core plugin functionality and cannot be self-hosted.
Service provider
- Opensolr — hosted Solr search cloud and AI API
- Privacy policy: https://opensolr.com/learn/privacy-policy
- Terms of service: https://opensolr.com/learn/terms-of-service
- Account signup (free tier available): https://opensolr.com/register
Endpoints the plugin contacts
https://opensolr.com/solr_manager/api/*— account management, index create/reload, config upload, sitemap registration, elevation toggle, crawl start/stop/stats. Called from WordPress admin (not from visitors’ browsers).https://api.opensolr.com/solr_manager/api/ingest— Data Ingestion API: pushes your post content + metadata to the search index. Called from the WordPress site (cron worker and the real-time sync on post save/delete), never from visitors.https://api.opensolr.com/solr_manager/api/embed— generates a 1024-dim semantic embedding for the current search query (AI/hybrid search path only). Called from the WordPress site on every AI/hybrid search.https://api.opensolr.com/solr_manager/api/ai_summary— streams the AI Hints / AI Reader answer. Called from the WordPress site only when the admin has enabled those features.https://<your-solr-host>.solrcluster.com/solr/<your-index>/select— the Solr search request itself (host provided by Opensolr when you create an index). Called from the WordPress site on every search.https://search.opensolr.com/embed.js— loaded ONLY if the admin switches Search Mode to “Embeddable”. In Native mode (the default), this script is never loaded.
Data sent to these services
- Your Opensolr email + API key (authentication).
- Your site’s host name (
meta_domain). - For ingestion: post titles, content, URL, excerpt, author display name, taxonomy terms, publish dates, WooCommerce price + category + SKU, featured-image URL. Only for the post types you explicitly enable in the plugin settings. Never includes user login data, email addresses, or passwords.
- For search: the search query string, the active facet filters, pagination position.
- For AI features (when enabled): the search query plus the top 4 result snippets, so the AI can compose an answer from your own content.
- For click tracking (when enabled): the clicked result URL, title, position, the search query, and a SHA-256 hash of the visitor’s IP (never the raw IP). Analytics can be disabled from the plugin’s Search Display settings.
No data is shared with any third party — all traffic goes only to opensolr.com / api.opensolr.com / *.solrcluster.com (and only to search.opensolr.com if you explicitly enable Embeddable mode).
Орнотуу
- Upload the
opensolr-searchfolder to/wp-content/plugins/ - Activate the plugin through the Plugins menu
- Go to Settings > Opensolr Search
- Enter your Opensolr email and API key
- Click “Save & Connect” to create or select a search index
- Register your sitemap and start the crawler
- Visit
/opensolr-searchto see your search page
FAQ.KG
-
Do I need an Opensolr account?
-
Yes. Opensolr Search uses the Opensolr hosted search infrastructure. You can sign up for free at opensolr.com. Keyword search works out of the box on every plan. AI features (vector search, AI Hints, AI Reader) are available on tailored plans.
-
Does this replace WordPress default search?
-
Yes. Once configured, the plugin provides a complete search experience at
/opensolr-searchwith faceted navigation, autocomplete, highlighting, and more. -
Does it work with WooCommerce?
-
Yes. The plugin automatically detects WooCommerce products and indexes them with prices, categories, SKUs, and structured product data.
-
What about multilingual sites?
-
The plugin supports WPML and Polylang. When a multilingual plugin is active, search results are automatically filtered to the current language.
-
How does indexing work?
-
Two methods: (1) The Web Crawler fetches your pages from the sitemap and indexes the content. (2) Data Ingestion pushes content directly from WordPress to Solr, with real-time sync on post save/delete and bulk async ingestion.
-
Where are search queries processed?
-
All search queries are sent directly from the visitor’s browser to the Opensolr cloud infrastructure. This means zero search load on your WordPress server.
-
Can I opt out of click/query tracking?
-
Yes. The Analytics toggle in the plugin settings disables all query and click logging. With Analytics disabled, nothing is written to the plugin’s local analytics tables. IP addresses are always SHA-256 hashed before storage regardless of this setting — raw IPs are never stored.
Сын-пикирлер
There are no reviews for this plugin.
Contributors & Developers
“Opensolr Search” is open source software. The following people have contributed to this plugin.
МүчөлөрүTranslate “Opensolr Search” into your language.
Interested in development?
Browse the code, check out the SVN repository, or subscribe to the development log by RSS.
Өзгөртүүлөр
1.0.21
- Fix: File / Document / Audio / Video media mappings now emit a real public
URL instead of the bare attachment ID. Previous versions only resolved
IMAGE attachments — mapping a PDF / DOCX / MP4 / MP3 attachment ID through
Facet Mapping silently kept the integer in Solr. Now any image, video,
audio, or known document MIME (PDF / DOC / DOCX / XLS / XLSX / PPT / PPTX
/ ODT / ODS / TXT) auto-resolves to its public URL. - Fix: ACF “Image Array” / “File Array” return format no longer pollutes
Solr with a mix of id + alt + title + url + width + height. The flatten
pass now detects the ACF attachment shape and emits ONE value per row —
theurlif present, otherwise theID(which then resolves through the
normal attachment-URL pipeline). Single-mode AND multi-mode mappings both
produce clean URL values. - Fix: Values that are already URLs (
http://…/https://…) pass through
unchanged — covers ACF “Return Format = URL” + hand-rolled custom-field
patterns. Previously the resolver only fired on numeric IDs, leaving
everything else as-is, which was already correct for URLs but is now
documented and explicit.
1.0.20
- New: Date-range quick presets on facet sidebar — every date_range facet
now renders three pill buttons (Today / Last Week / Last Month) above the
From/To inputs. One click fills both dates and submits the facet form — no
more opening the native date picker twice for common queries. Uses LOCAL
date components (not toISOString) so “Today” stays today in every timezone. - New: Data Ingestion tab — live “Total: N documents” tally and dynamic
per-type counts. Check or uncheck a content type and the number next to
that type flips between its real count and 0, with the grand total at the
bottom of the fieldset updating instantly. Mirrors the Drupal module’s
ingestion UX. Include attached files toggle also contributes to the total.
1.0.19
First public release since 1.0.14. Rolls up every intermediate deploy.
* New: Facet Mapping form now matches the Drupal module — Solr Field
Name + Solr Type dropdown + Display Label. Pick a WP field and the
Solr Type auto-fills from the detected suffix; stem auto-fills from
the WP field name. Type hints shown next to every entry in the
WordPress Field dropdown (post_tag multi, string; price single,
float; etc.).
* New: WordPress Field dropdown shows every indexable source, not just
a handful of postmeta keys. Core post columns (post_title,
post_content, post_excerpt, post_date, post_status, post_type,
post_author), ALL postmeta (underscore-prefixed included —
_price/_sku/_stock/_thumbnail_id are now mappable), register_meta()
keys, every public taxonomy, all pa* WooCommerce attribute
taxonomies, plus synthetic featured_image_url and gallery_image_urls.
* New: Core post columns and WC synthetic aggregates resolve end-to-end
in both ingestion and tag emission.
* Fix: Facet Mapping saves no longer silently drop every row. The
sanitize callback hooked via register_setting() expected the legacy
flat scalar shape and called is_scalar($dst) on each value — every
row in the new rich {wp_field, meta_name, field_type, label,
solr_field} shape was failing the check and being stripped under
sanitize_option_opensolr_settings. Callback now accepts both shapes.
* Fix: Multi-valued mappings stored as serialized arrays in a single
postmeta row (ACF Checkbox / Select multi / Relationship / Gallery
fields, WooCommerce attributes) now emit one per value and
serialize as Solr arrays. Both emission and ingestion paths flatten
across both WP storage patterns (multi-row AND single-row-with-array).
* Fix: Admin scripts self-invalidate on every deploy via filemtime()
cache-busting. Previously OPENSOLR_VERSION-based cache-busting meant
every intermediate fix shipped to disk without browsers refetching.
* Fix: Facet Mapping table always renders at least one empty row so
the admin has a visible slot to click into.
* Fix: + Add Field Mapping button no longer collides with the
placeholder row’s index.
* Fix: Backend stem fallback — save handler derives the Solr Field
Name from the WP field name when left empty, preventing silent row
drops on incomplete input.
1.0.14
- Fix: image-field Facet Mappings now emit a real image URL. Previously,
mapping a meta key that stores an attachment ID (ACF image field
returning “ID”,_thumbnail_id, custom image_attachment_id, etc.) to
a Solr field emitted the bare integer as the meta content — useless
as an image source. Both ingestion and meta-tag emission now
auto-resolve numeric values towp_get_attachment_url()when the ID
points at a valid image attachment. SKU, price, and other numeric
fields are untouched (guarded bywp_attachment_is_image()).
1.0.13
- Fix: Persistent Filters “Exclude” mode was silently saved as “Include”.
The register_setting() sanitize callback used aop: include/exclude
shape that didn’t match themode: +/-shape the admin form writes
and the query builder reads, so any-(Exclude) selection was
overwritten with the default on save. Existing stuck filters need to
be re-saved after upgrading to pick up the correct mode.
1.0.12
- New: combobox autocomplete on “Solr field for result image” in Search
Display. Focusing the input drops down the full alphabetical list of
Solr fields indexed on your site (from the Luke handler); typing
filters by case-insensitive substring match. Keyboard navigation
(arrows + Enter) and mouse picking supported. New admin-only REST
endpoint/opensolr/v1/luke-fieldswith amanage_options
permission_callback feeds the list. JS and CSS enqueued via
wp_enqueue_script /wp_enqueue_style(no inline tags); URL and
nonce passed viawp_localize_script; all output escaped; DOM-based
rendering avoids innerHTML. Plain typing still works for field names
that aren’t indexed yet.
1.0.11
- New: “Solr field for result image” input in Search Display settings.
Defaultog_image. Lets admins point result thumbnails at any
single-valued Solr field they’ve mapped through Facet Mapping
(WordPress post meta, WooCommerce gallery, custom URL field, etc.).
Applies to the search results page, the AI Reader modal, and the
AI Reader metadata endpoint. Multi-valued sources normalized to the
first element. Empty or non-alphanumeric input falls back to og_image.
1.0.10
- Fixed: Facet Mapping entries targeting multi-valued Solr fields
(_sm/_fm/_im/_dtm) now work correctly with both the Web Crawler
and Data Ingestion paths. Previously the ingest path was broken entirely
for field mappings (reading config keys the admin UI never wrote), and
the meta-tag emission concatenated array values into a single
comma-joined string. Now:- Ingest parses the suffix out of
solr_fieldto determine multi vs
single, and writes arrays directly to Solr. - Meta-tag emission writes one
<meta property="opensolr:X_sm">tag
per value so the Opensolr crawler can aggregate them back into an
array (DOM order preserved). - Hardcoded emissions for
product_images_smand variable product
attribute*_smfields updated to the same repeated-tag pattern.
Pairs with a crawler update that aggregates repeatedopensolr:*tags.
- Ingest parses the suffix out of
1.0.9
- Security: register_setting() sanitize_callback now applies per-field
sanitization (sanitize_text_field, sanitize_email, absint, float clamping,
strict enum allowlists, recursive array sanitization for facets / filters /
content type lists). Previous callback only merged input, relying on
caller-side sanitization. - Security: REST /queue-stats endpoint now requires manage_options. The
endpoint feeds the Data Crawler admin UI (live preview counts for arbitrary
content-type overrides), so it’s an admin-configuration surface and should
not be public. - Compliance: JSON-LD structured-data blocks (WebSite SearchAction, Article,
BreadcrumbList) now output via wp_print_inline_script_tag() instead of
echoing raw tags. Same XSS protection (JSON_HEX_TAG | JSON_HEX_AMP
prevents script breakout) — just routed through WordPress’s official helper. - Dependency: Chart.js bundled library updated from 4.5.0 to 4.5.1.
1.0.7
- New: Lexical Only search mode in Search Tuning Search Mode. Explicit
opt-out from vector — no embedding API call is made, search runs straight
through the lexical edismax path. Useful for deterministic BM25 ranking,
avoiding embed API latency, or users on plans without vector who want
explicit control instead of the implicit server-side fallback. - New: When Lexical Only is selected, the Minimum Relevance Score slider
auto-zeros itself. That threshold is calibrated for the combined hybrid
score and would filter out every result in pure lexical mode. Backend
forces the value to 0 on save and at query time; JS zeroes the slider
live the moment the radio is picked. A yellow note explains the coupling. - Change: Lexical-only fallback now uses defType=edismax + raw q (idiomatic
Solr style) instead of q={!bool should=$lexicalQuery}. Same behavior,
cleaner in the Query Inspector, matches the opensolr search_lexical()
method for cross-platform consistency. - Change: Plugin version bumped so browsers pick up the new admin-ui JS
handler for the bool_mode radios.
1.0.5
- New: Minimum Relevance Score slider in Search Tuning. Drops results whose
combined {!bool}(lexical + vector) score falls below the threshold, cleaning
noise from facet counts and result totals. Applied as a Solr frange
post-filter on the hybrid score. Needed because the {!func}-wrapped lexical
side of the {!bool} matches every doc (score 0 for non-lexical hits) and
KNN topK returns N candidates regardless of cosine similarity — without this
filter numFound balloons to the entire base filter set and facet counts get
polluted. Default 0.3; legitimate matches easily clear it. Slider moves in
0.1 increments, 0 disables the filter. - Change: Plugin version bumped so browsers pick up the new admin-ui JS.
Without the bump, cached old JS had no listener for the new slider and its
live label wouldn’t update while dragging.
1.0.4
- Improvement: The Semantic Lexical Balance slider is now a true balance dial.
Previously it just scaled the qf/pf field-weight boosts linearly (same effect
as lowering the weights themselves). The lexical score is now reshaped via
pow(BM25 + 1, lexical_weight) – 1, so the slider changes the SHAPE of the
lexical contribution curve, not just its magnitude:- 1.0 = linear (full BM25, named entities dominate)
- 0.5 = sqrt-like compression (balanced, new default)
- 0.2 = heavy compression (vector takes over)
- 0.1 = lexical almost off
- Change: Default Title field weight raised from 0.03 to 0.1 and default
Semantic Lexical Balance raised from 0.20 to 0.50. These defaults work
better with the new pow reshape across a wide range of corpora. - Removed: Misleading “field weights are automatically overridden to 0”
banner in Search Tuning — no longer applies after the hybrid ranking fix
in 1.0.3.
1.0.3
- Fix: Hybrid search ranking ignored query keywords. In vector hybrid mode the
lexical qf was hardcoded to zero, so proper nouns, product names and other
specific terms contributed nothing to scoring — results were ranked purely
on semantic similarity, which pushed near-duplicate neighbours ahead of exact
matches. Field weights from Search Tuning now apply alongside the KNN vector
score as designed.
1.0.2
- Fix: Filters button on mobile search page now toggles the facet sidebar
(class-name mismatch between template, CSS and JS — JS was listening on
the old selectors left over from an earlier refactor).
1.0.1
- Plugin-review compliance pass (no functional changes):
- Moved all inline
<script>and<style>blocks into enqueued.jsand.cssfiles (wp_enqueue_script / wp_enqueue_style / wp_localize_script) - Refactored all $wpdb->prepare() calls to inline placeholders (fixes Plugin Check InterpolatedNotPrepared + UnfinishedPrepare warnings)
- Tightened JSON-LD output escaping: JSON_HEX_TAG | JSON_HEX_AMP to prevent any possible breakout
- esc_url_raw esc_url wherever a URL is written into an output context
- Added opt-out for local analytics logging (Search Display Analytics toggle)
- Documented every external service, endpoint and data flow in the “External services” section above
- Updated bundled libraries: Chart.js 4.5.0, marked 15.0.12, SortableJS 1.15.6
1.0.0
- Initial release
- Hybrid vector + keyword search
- Faceted navigation with list, slider, date range, and hierarchical widgets
- AI Hints and AI Reader streaming
- Autocomplete with query suggestions
- WooCommerce product support
- Web Crawler and Data Ingestion indexing
- Search analytics with CTR tracking
- Query Elevation (pin/exclude results)
- Persistent admin filters
- Multilingual support (WPML, Polylang)
- Dark theme
- Embeddable search widget mode
- Meta tag and JSON-LD injection for SEO
- XML sitemap generation
