{"id":300315,"date":"2026-04-24T09:17:32","date_gmt":"2026-04-24T09:17:32","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/opensolr-search\/"},"modified":"2026-04-27T10:40:45","modified_gmt":"2026-04-27T10:40:45","slug":"opensolr-search","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/opensolr-search\/","author":23480003,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.21","stable_tag":"1.0.21","tested":"6.9.4","requires":"6.0","requires_php":"8.1","requires_plugins":null,"header_name":"Opensolr Search","header_author":"Dimofte Ciprian - Opensolr SRL","header_description":"Full-text hybrid search powered by Opensolr. AI-powered vector + lexical search, faceted navigation, autocomplete, analytics, and WooCommerce support \u2014 zero indexing load on WordPress.","assets_banners_color":"423e47","last_updated":"2026-04-27 10:40:45","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/opensolr.com\/opensolr-platform-user-documentation","header_author_uri":"https:\/\/opensolr.com","rating":0,"author_block_rating":0,"active_installs":0,"downloads":185,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.12":{"tag":"1.0.12","author":"opensolr","date":"2026-04-24 09:16:33"},"1.0.13":{"tag":"1.0.13","author":"opensolr","date":"2026-04-24 10:11:04"},"1.0.14":{"tag":"1.0.14","author":"opensolr","date":"2026-04-24 10:47:06"},"1.0.19":{"tag":"1.0.19","author":"opensolr","date":"2026-04-24 13:46:14"},"1.0.20":{"tag":"1.0.20","author":"opensolr","date":"2026-04-24 14:36:27"},"1.0.21":{"tag":"1.0.21","author":"opensolr","date":"2026-04-27 10:40:45"}},"upgrade_notice":{"1.0.9":"<p>Plugin-review compliance pass \u2014 per-field setting sanitization, admin-only\nqueue-stats endpoint, JSON-LD via wp_print_inline_script_tag(), Chart.js 4.5.1.\nSafe to update.<\/p>","1.0.2":"<p>Bug fix: mobile Filters button. Safe to update.<\/p>","1.0.1":"<p>Plugin-review compliance pass \u2014 no functional changes. Safe to update.<\/p>","1.0.0":"<p>Initial release.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3514447,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3514447,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3514447,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3514447,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.12","1.0.13","1.0.14","1.0.19","1.0.20","1.0.21"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"Search results page with faceted navigation","2":"Admin settings panel","3":"Search analytics dashboard","4":"Facet mapping configuration"}},"plugin_section":[],"plugin_tags":[3226,28913,944,5012,5184],"plugin_category":[],"plugin_contributors":[260987],"plugin_business_model":[],"class_list":["post-300315","plugin","type-plugin","status-publish","hentry","plugin_tags-autocomplete","plugin_tags-faceted-search","plugin_tags-search","plugin_tags-solr","plugin_tags-woocommerce-search","plugin_contributors-opensolr","plugin_committers-opensolr"],"banners":{"banner":"https:\/\/ps.w.org\/opensolr-search\/assets\/banner-772x250.png?rev=3514447","banner_2x":"https:\/\/ps.w.org\/opensolr-search\/assets\/banner-1544x500.png?rev=3514447","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/opensolr-search\/assets\/icon-128x128.png?rev=3514447","icon_2x":"https:\/\/ps.w.org\/opensolr-search\/assets\/icon-256x256.png?rev=3514447","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>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.<\/p>\n\n<p><strong>Key Features:<\/strong><\/p>\n\n<ul>\n<li><strong>Hybrid Search<\/strong> \u2014 combines keyword matching (BM25) with semantic vector search (1024-dim embeddings) for the best of both worlds<\/li>\n<li><strong>Faceted Navigation<\/strong> \u2014 filter results by category, price range, date, custom fields, and hierarchical taxonomies<\/li>\n<li><strong>AI Hints<\/strong> \u2014 streaming AI-generated answers above search results, powered by RAG<\/li>\n<li><strong>AI Reader<\/strong> \u2014 full-screen AI summary of any search result<\/li>\n<li><strong>Autocomplete<\/strong> \u2014 real-time search suggestions with query history and Solr results<\/li>\n<li><strong>WooCommerce Support<\/strong> \u2014 index products with prices, categories, SKUs, and structured data<\/li>\n<li><strong>Two Indexing Methods<\/strong> \u2014 Web Crawler (automatic) and Data Ingestion API (push from WordPress)<\/li>\n<li><strong>Search Analytics<\/strong> \u2014 track queries, clicks, CTR, no-results queries, and visitor patterns<\/li>\n<li><strong>Query Elevation<\/strong> \u2014 pin or exclude specific results for any query<\/li>\n<li><strong>Persistent Filters<\/strong> \u2014 admin-defined include\/exclude filters applied to every search<\/li>\n<li><strong>Multilingual<\/strong> \u2014 automatic locale filtering for WPML and Polylang sites<\/li>\n<li><strong>Dark Theme<\/strong> \u2014 built-in dark mode for the search page<\/li>\n<li><strong>Embeddable<\/strong> \u2014 use native search or embed the Opensolr hosted search widget<\/li>\n<\/ul>\n\n<p><strong>How It Works:<\/strong><\/p>\n\n<ol>\n<li>Sign up at <a href=\"https:\/\/opensolr.com\">opensolr.com<\/a> and get your API key<\/li>\n<li>Install the plugin and enter your credentials<\/li>\n<li>Create a search index or connect to an existing one<\/li>\n<li>Configure your sitemap and start the web crawler<\/li>\n<li>Your search page is live at <code>\/opensolr-search<\/code><\/li>\n<\/ol>\n\n<p>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 \u2014 all search queries go directly to the Opensolr cloud.<\/p>\n\n<p><strong>Requirements:<\/strong><\/p>\n\n<ul>\n<li>An Opensolr account (free tier available)<\/li>\n<li>PHP 8.1 or higher<\/li>\n<li>WordPress 6.0 or higher<\/li>\n<\/ul>\n\n<h3>External services<\/h3>\n\n<p>This plugin depends on several online services operated by Opensolr (<a href=\"https:\/\/opensolr.com\">https:\/\/opensolr.com<\/a>) 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.<\/p>\n\n<p><strong>Service provider<\/strong><\/p>\n\n<ul>\n<li>Opensolr \u2014 hosted Solr search cloud and AI API<\/li>\n<li>Privacy policy: <a href=\"https:\/\/opensolr.com\/learn\/privacy-policy\">https:\/\/opensolr.com\/learn\/privacy-policy<\/a><\/li>\n<li>Terms of service: <a href=\"https:\/\/opensolr.com\/learn\/terms-of-service\">https:\/\/opensolr.com\/learn\/terms-of-service<\/a><\/li>\n<li>Account signup (free tier available): <a href=\"https:\/\/opensolr.com\/register\">https:\/\/opensolr.com\/register<\/a><\/li>\n<\/ul>\n\n<p><strong>Endpoints the plugin contacts<\/strong><\/p>\n\n<ul>\n<li><code>https:\/\/opensolr.com\/solr_manager\/api\/*<\/code> \u2014 account management, index create\/reload, config upload, sitemap registration, elevation toggle, crawl start\/stop\/stats. Called from WordPress admin (not from visitors' browsers).<\/li>\n<li><code>https:\/\/api.opensolr.com\/solr_manager\/api\/ingest<\/code> \u2014 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.<\/li>\n<li><code>https:\/\/api.opensolr.com\/solr_manager\/api\/embed<\/code> \u2014 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.<\/li>\n<li><code>https:\/\/api.opensolr.com\/solr_manager\/api\/ai_summary<\/code> \u2014 streams the AI Hints \/ AI Reader answer. Called from the WordPress site only when the admin has enabled those features.<\/li>\n<li><code>https:\/\/&lt;your-solr-host&gt;.solrcluster.com\/solr\/&lt;your-index&gt;\/select<\/code> \u2014 the Solr search request itself (host provided by Opensolr when you create an index). Called from the WordPress site on every search.<\/li>\n<li><code>https:\/\/search.opensolr.com\/embed.js<\/code> \u2014 loaded ONLY if the admin switches Search Mode to \"Embeddable\". In Native mode (the default), this script is never loaded.<\/li>\n<\/ul>\n\n<p><strong>Data sent to these services<\/strong><\/p>\n\n<ul>\n<li>Your Opensolr email + API key (authentication).<\/li>\n<li>Your site's host name (<code>meta_domain<\/code>).<\/li>\n<li>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.<\/li>\n<li>For search: the search query string, the active facet filters, pagination position.<\/li>\n<li>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.<\/li>\n<li>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.<\/li>\n<\/ul>\n\n<p>No data is shared with any third party \u2014 all traffic goes only to <code>opensolr.com<\/code> \/ <code>api.opensolr.com<\/code> \/ <code>*.solrcluster.com<\/code> (and only to <code>search.opensolr.com<\/code> if you explicitly enable Embeddable mode).<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>opensolr-search<\/code> folder to <code>\/wp-content\/plugins\/<\/code><\/li>\n<li>Activate the plugin through the Plugins menu<\/li>\n<li>Go to Settings &gt; Opensolr Search<\/li>\n<li>Enter your Opensolr email and API key<\/li>\n<li>Click \"Save &amp; Connect\" to create or select a search index<\/li>\n<li>Register your sitemap and start the crawler<\/li>\n<li>Visit <code>\/opensolr-search<\/code> to see your search page<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"do%20i%20need%20an%20opensolr%20account%3F\"><h3>Do I need an Opensolr account?<\/h3><\/dt>\n<dd><p>Yes. Opensolr Search uses the Opensolr hosted search infrastructure. You can sign up for free at <a href=\"https:\/\/opensolr.com\">opensolr.com<\/a>. Keyword search works out of the box on every plan. AI features (vector search, AI Hints, AI Reader) are available on tailored plans.<\/p><\/dd>\n<dt id=\"does%20this%20replace%20wordpress%20default%20search%3F\"><h3>Does this replace WordPress default search?<\/h3><\/dt>\n<dd><p>Yes. Once configured, the plugin provides a complete search experience at <code>\/opensolr-search<\/code> with faceted navigation, autocomplete, highlighting, and more.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20woocommerce%3F\"><h3>Does it work with WooCommerce?<\/h3><\/dt>\n<dd><p>Yes. The plugin automatically detects WooCommerce products and indexes them with prices, categories, SKUs, and structured product data.<\/p><\/dd>\n<dt id=\"what%20about%20multilingual%20sites%3F\"><h3>What about multilingual sites?<\/h3><\/dt>\n<dd><p>The plugin supports WPML and Polylang. When a multilingual plugin is active, search results are automatically filtered to the current language.<\/p><\/dd>\n<dt id=\"how%20does%20indexing%20work%3F\"><h3>How does indexing work?<\/h3><\/dt>\n<dd><p>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.<\/p><\/dd>\n<dt id=\"where%20are%20search%20queries%20processed%3F\"><h3>Where are search queries processed?<\/h3><\/dt>\n<dd><p>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.<\/p><\/dd>\n<dt id=\"can%20i%20opt%20out%20of%20click%2Fquery%20tracking%3F\"><h3>Can I opt out of click\/query tracking?<\/h3><\/dt>\n<dd><p>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 \u2014 raw IPs are never stored.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.21<\/h4>\n\n<ul>\n<li>Fix: File \/ Document \/ Audio \/ Video media mappings now emit a real public\nURL instead of the bare attachment ID. Previous versions only resolved\nIMAGE attachments \u2014 mapping a PDF \/ DOCX \/ MP4 \/ MP3 attachment ID through\nFacet Mapping silently kept the integer in Solr. Now any image, video,\naudio, or known document MIME (PDF \/ DOC \/ DOCX \/ XLS \/ XLSX \/ PPT \/ PPTX\n\/ ODT \/ ODS \/ TXT) auto-resolves to its public URL.<\/li>\n<li>Fix: ACF \"Image Array\" \/ \"File Array\" return format no longer pollutes\nSolr with a mix of id + alt + title + url + width + height. The flatten\npass now detects the ACF attachment shape and emits ONE value per row \u2014\nthe <code>url<\/code> if present, otherwise the <code>ID<\/code> (which then resolves through the\nnormal attachment-URL pipeline). Single-mode AND multi-mode mappings both\nproduce clean URL values.<\/li>\n<li>Fix: Values that are already URLs (<code>http:\/\/\u2026<\/code> \/ <code>https:\/\/\u2026<\/code>) pass through\nunchanged \u2014 covers ACF \"Return Format = URL\" + hand-rolled custom-field\npatterns. Previously the resolver only fired on numeric IDs, leaving\neverything else as-is, which was already correct for URLs but is now\ndocumented and explicit.<\/li>\n<\/ul>\n\n<h4>1.0.20<\/h4>\n\n<ul>\n<li>New: Date-range quick presets on facet sidebar \u2014 every date_range facet\nnow renders three pill buttons (Today \/ Last Week \/ Last Month) above the\nFrom\/To inputs. One click fills both dates and submits the facet form \u2014 no\nmore opening the native date picker twice for common queries. Uses LOCAL\ndate components (not toISOString) so \"Today\" stays today in every timezone.<\/li>\n<li>New: Data Ingestion tab \u2014 live \"Total: N documents\" tally and dynamic\nper-type counts. Check or uncheck a content type and the number next to\nthat type flips between its real count and 0, with the grand total at the\nbottom of the fieldset updating instantly. Mirrors the Drupal module's\ningestion UX. Include attached files toggle also contributes to the total.<\/li>\n<\/ul>\n\n<h4>1.0.19<\/h4>\n\n<p>First public release since 1.0.14. Rolls up every intermediate deploy.\n* New: Facet Mapping form now matches the Drupal module \u2014 Solr Field\n  Name + Solr Type dropdown + Display Label. Pick a WP field and the\n  Solr Type auto-fills from the detected suffix; stem auto-fills from\n  the WP field name. Type hints shown next to every entry in the\n  WordPress Field dropdown (post_tag \u2192 multi, string; <em>price \u2192 single,\n  float; etc.).\n* New: WordPress Field dropdown shows every indexable source, not just\n  a handful of postmeta keys. Core post columns (post_title,\n  post_content, post_excerpt, post_date, post_status, post_type,\n  post_author), ALL postmeta (underscore-prefixed included \u2014\n  _price\/_sku\/_stock\/_thumbnail_id are now mappable), register_meta()\n  keys, every public taxonomy, all pa<\/em>* WooCommerce attribute\n  taxonomies, plus synthetic featured_image_url and gallery_image_urls.\n* New: Core post columns and WC synthetic aggregates resolve end-to-end\n  in both ingestion and  tag emission.\n* Fix: Facet Mapping saves no longer silently drop every row. The\n  sanitize callback hooked via register_setting() expected the legacy\n  flat scalar shape and called is_scalar($dst) on each value \u2014 every\n  row in the new rich {wp_field, meta_name, field_type, label,\n  solr_field} shape was failing the check and being stripped under\n  sanitize_option_opensolr_settings. Callback now accepts both shapes.\n* Fix: Multi-valued mappings stored as serialized arrays in a single\n  postmeta row (ACF Checkbox \/ Select multi \/ Relationship \/ Gallery\n  fields, WooCommerce attributes) now emit one  per value and\n  serialize as Solr arrays. Both emission and ingestion paths flatten\n  across both WP storage patterns (multi-row AND single-row-with-array).\n* Fix: Admin scripts self-invalidate on every deploy via filemtime()\n  cache-busting. Previously OPENSOLR_VERSION-based cache-busting meant\n  every intermediate fix shipped to disk without browsers refetching.\n* Fix: Facet Mapping table always renders at least one empty row so\n  the admin has a visible slot to click into.\n* Fix: + Add Field Mapping button no longer collides with the\n  placeholder row's index.\n* Fix: Backend stem fallback \u2014 save handler derives the Solr Field\n  Name from the WP field name when left empty, preventing silent row\n  drops on incomplete input.<\/p>\n\n<h4>1.0.14<\/h4>\n\n<ul>\n<li>Fix: image-field Facet Mappings now emit a real image URL. Previously,\nmapping a meta key that stores an attachment ID (ACF image field\nreturning \"ID\", <code>_thumbnail_id<\/code>, custom image_attachment_id, etc.) to\na Solr field emitted the bare integer as the meta content \u2014 useless\nas an image source. Both ingestion and meta-tag emission now\nauto-resolve numeric values to <code>wp_get_attachment_url()<\/code> when the ID\npoints at a valid image attachment. SKU, price, and other numeric\nfields are untouched (guarded by <code>wp_attachment_is_image()<\/code>).<\/li>\n<\/ul>\n\n<h4>1.0.13<\/h4>\n\n<ul>\n<li>Fix: Persistent Filters \"Exclude\" mode was silently saved as \"Include\".\nThe register_setting() sanitize callback used a <code>op: include\/exclude<\/code>\nshape that didn't match the <code>mode: +\/-<\/code> shape the admin form writes\nand the query builder reads, so any <code>-<\/code> (Exclude) selection was\noverwritten with the default on save. Existing stuck filters need to\nbe re-saved after upgrading to pick up the correct mode.<\/li>\n<\/ul>\n\n<h4>1.0.12<\/h4>\n\n<ul>\n<li>New: combobox autocomplete on \"Solr field for result image\" in Search\nDisplay. Focusing the input drops down the full alphabetical list of\nSolr fields indexed on your site (from the Luke handler); typing\nfilters by case-insensitive substring match. Keyboard navigation\n(arrows + Enter) and mouse picking supported. New admin-only REST\nendpoint <code>\/opensolr\/v1\/luke-fields<\/code> with a <code>manage_options<\/code>\npermission_callback feeds the list. JS and CSS enqueued via\n  wp_enqueue_script \/ <code>wp_enqueue_style<\/code> (no inline tags); URL and\nnonce passed via <code>wp_localize_script<\/code>; all output escaped; DOM-based\nrendering avoids innerHTML. Plain typing still works for field names\nthat aren't indexed yet.<\/li>\n<\/ul>\n\n<h4>1.0.11<\/h4>\n\n<ul>\n<li>New: \"Solr field for result image\" input in Search Display settings.\nDefault <code>og_image<\/code>. Lets admins point result thumbnails at any\nsingle-valued Solr field they've mapped through Facet Mapping\n(WordPress post meta, WooCommerce gallery, custom URL field, etc.).\nApplies to the search results page, the AI Reader modal, and the\nAI Reader metadata endpoint. Multi-valued sources normalized to the\nfirst element. Empty or non-alphanumeric input falls back to og_image.<\/li>\n<\/ul>\n\n<h4>1.0.10<\/h4>\n\n<ul>\n<li>Fixed: Facet Mapping entries targeting multi-valued Solr fields\n(<code>_sm<\/code>\/<code>_fm<\/code>\/<code>_im<\/code>\/<code>_dtm<\/code>) now work correctly with both the Web Crawler\nand Data Ingestion paths. Previously the ingest path was broken entirely\nfor field mappings (reading config keys the admin UI never wrote), and\nthe meta-tag emission concatenated array values into a single\ncomma-joined string. Now:\n\n<ul>\n<li>Ingest parses the suffix out of <code>solr_field<\/code> to determine multi vs\nsingle, and writes arrays directly to Solr.<\/li>\n<li>Meta-tag emission writes one <code>&lt;meta property=\"opensolr:X_sm\"&gt;<\/code> tag\nper value so the Opensolr crawler can aggregate them back into an\narray (DOM order preserved).<\/li>\n<li>Hardcoded emissions for <code>product_images_sm<\/code> and variable product\nattribute <code>*_sm<\/code> fields updated to the same repeated-tag pattern.\nPairs with a crawler update that aggregates repeated <code>opensolr:*<\/code> tags.<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>1.0.9<\/h4>\n\n<ul>\n<li>Security: register_setting() sanitize_callback now applies per-field\nsanitization (sanitize_text_field, sanitize_email, absint, float clamping,\nstrict enum allowlists, recursive array sanitization for facets \/ filters \/\ncontent type lists). Previous callback only merged input, relying on\ncaller-side sanitization.<\/li>\n<li>Security: REST \/queue-stats endpoint now requires manage_options. The\nendpoint feeds the Data Crawler admin UI (live preview counts for arbitrary\ncontent-type overrides), so it's an admin-configuration surface and should\nnot be public.<\/li>\n<li>Compliance: JSON-LD structured-data blocks (WebSite SearchAction, Article,\nBreadcrumbList) now output via wp_print_inline_script_tag() instead of\nechoing raw  tags. Same XSS protection (JSON_HEX_TAG | JSON_HEX_AMP\nprevents script breakout) \u2014 just routed through WordPress's official helper.<\/li>\n<li>Dependency: Chart.js bundled library updated from 4.5.0 to 4.5.1.<\/li>\n<\/ul>\n\n<h4>1.0.7<\/h4>\n\n<ul>\n<li>New: Lexical Only search mode in Search Tuning \u2192 Search Mode. Explicit\nopt-out from vector \u2014 no embedding API call is made, search runs straight\nthrough the lexical edismax path. Useful for deterministic BM25 ranking,\navoiding embed API latency, or users on plans without vector who want\nexplicit control instead of the implicit server-side fallback.<\/li>\n<li>New: When Lexical Only is selected, the Minimum Relevance Score slider\nauto-zeros itself. That threshold is calibrated for the combined hybrid\nscore and would filter out every result in pure lexical mode. Backend\nforces the value to 0 on save and at query time; JS zeroes the slider\nlive the moment the radio is picked. A yellow note explains the coupling.<\/li>\n<li>Change: Lexical-only fallback now uses defType=edismax + raw q (idiomatic\nSolr style) instead of q={!bool should=$lexicalQuery}. Same behavior,\ncleaner in the Query Inspector, matches the opensolr search_lexical()\nmethod for cross-platform consistency.<\/li>\n<li>Change: Plugin version bumped so browsers pick up the new admin-ui JS\nhandler for the bool_mode radios.<\/li>\n<\/ul>\n\n<h4>1.0.5<\/h4>\n\n<ul>\n<li>New: Minimum Relevance Score slider in Search Tuning. Drops results whose\ncombined {!bool}(lexical + vector) score falls below the threshold, cleaning\nnoise from facet counts and result totals. Applied as a Solr frange\npost-filter on the hybrid score. Needed because the {!func}-wrapped lexical\nside of the {!bool} matches every doc (score 0 for non-lexical hits) and\nKNN topK returns N candidates regardless of cosine similarity \u2014 without this\nfilter numFound balloons to the entire base filter set and facet counts get\npolluted. Default 0.3; legitimate matches easily clear it. Slider moves in\n0.1 increments, 0 disables the filter.<\/li>\n<li>Change: Plugin version bumped so browsers pick up the new admin-ui JS.\nWithout the bump, cached old JS had no listener for the new slider and its\nlive label wouldn't update while dragging.<\/li>\n<\/ul>\n\n<h4>1.0.4<\/h4>\n\n<ul>\n<li>Improvement: The Semantic \u2194 Lexical Balance slider is now a true balance dial.\nPreviously it just scaled the qf\/pf field-weight boosts linearly (same effect\nas lowering the weights themselves). The lexical score is now reshaped via\npow(BM25 + 1, lexical_weight) - 1, so the slider changes the SHAPE of the\nlexical contribution curve, not just its magnitude:\n\n<ul>\n<li>1.0 = linear (full BM25, named entities dominate)<\/li>\n<li>0.5 = sqrt-like compression (balanced, new default)<\/li>\n<li>0.2 = heavy compression (vector takes over)<\/li>\n<li>0.1 = lexical almost off<\/li>\n<\/ul><\/li>\n<li>Change: Default Title field weight raised from 0.03 to 0.1 and default\nSemantic \u2194 Lexical Balance raised from 0.20 to 0.50. These defaults work\nbetter with the new pow reshape across a wide range of corpora.<\/li>\n<li>Removed: Misleading \"field weights are automatically overridden to 0\"\nbanner in Search Tuning \u2014 no longer applies after the hybrid ranking fix\nin 1.0.3.<\/li>\n<\/ul>\n\n<h4>1.0.3<\/h4>\n\n<ul>\n<li>Fix: Hybrid search ranking ignored query keywords. In vector hybrid mode the\nlexical qf was hardcoded to zero, so proper nouns, product names and other\nspecific terms contributed nothing to scoring \u2014 results were ranked purely\non semantic similarity, which pushed near-duplicate neighbours ahead of exact\nmatches. Field weights from Search Tuning now apply alongside the KNN vector\nscore as designed.<\/li>\n<\/ul>\n\n<h4>1.0.2<\/h4>\n\n<ul>\n<li>Fix: Filters button on mobile search page now toggles the facet sidebar\n(class-name mismatch between template, CSS and JS \u2014 JS was listening on\nthe old selectors left over from an earlier refactor).<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Plugin-review compliance pass (no functional changes):<\/li>\n<li>Moved all inline <code>&lt;script&gt;<\/code> and <code>&lt;style&gt;<\/code> blocks into enqueued <code>.js<\/code> and <code>.css<\/code> files (wp_enqueue_script \/ wp_enqueue_style \/ wp_localize_script)<\/li>\n<li>Refactored all $wpdb-&gt;prepare() calls to inline placeholders (fixes Plugin Check InterpolatedNotPrepared + UnfinishedPrepare warnings)<\/li>\n<li>Tightened JSON-LD output escaping: JSON_HEX_TAG | JSON_HEX_AMP to prevent any possible  breakout<\/li>\n<li>esc_url_raw \u2192 esc_url wherever a URL is written into an output context<\/li>\n<li>Added opt-out for local analytics logging (Search Display \u2192 Analytics toggle)<\/li>\n<li>Documented every external service, endpoint and data flow in the \"External services\" section above<\/li>\n<li>Updated bundled libraries: Chart.js 4.5.0, marked 15.0.12, SortableJS 1.15.6<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release<\/li>\n<li>Hybrid vector + keyword search<\/li>\n<li>Faceted navigation with list, slider, date range, and hierarchical widgets<\/li>\n<li>AI Hints and AI Reader streaming<\/li>\n<li>Autocomplete with query suggestions<\/li>\n<li>WooCommerce product support<\/li>\n<li>Web Crawler and Data Ingestion indexing<\/li>\n<li>Search analytics with CTR tracking<\/li>\n<li>Query Elevation (pin\/exclude results)<\/li>\n<li>Persistent admin filters<\/li>\n<li>Multilingual support (WPML, Polylang)<\/li>\n<li>Dark theme<\/li>\n<li>Embeddable search widget mode<\/li>\n<li>Meta tag and JSON-LD injection for SEO<\/li>\n<li>XML sitemap generation<\/li>\n<\/ul>","raw_excerpt":"Powerful hybrid vector + keyword search powered by Opensolr. AI-powered search, faceted navigation, autocomplete, analytics, and WooCommerce support.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/300315","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=300315"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/opensolr"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=300315"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=300315"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=300315"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=300315"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=300315"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=300315"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}