Giter VIP home page Giter VIP logo

doofinder's Introduction

DooFinder Bundle

Prerequisites

stats_screenshot

Installation

composer

just run:

composer require asioso/pimcore-doofinder:dev-master

Extension manager

just enable and install the Bundle in the pimcore extension manager.

Configuration

what's absolutely necessary to be added to your config.yml file:

doo_finder:
    search_api_key: "<search-api-key>"
    management_api_key: "<management-api-key>"

Define your Engine Configurations

Take a look here for a deeper insights on the internal workings of this bundle, but in short: doofinder let's you define multiple search engines for your account. Each of these engines might have several types (so to say indices) for content. Each type's content might greatly differ in structure and content, however they all must share the same language-property (also currency!) from their parent engine.

So why does this matter?

For example you want to put your webshop's products from pimcore to doofinder. Let's say you have active localization for German (DE) und English (EN) and Prices in Euro(€) and Pound(£). That would mean you would still have to create two search engines in doofinder, one for each language respectively.

So you will have add the following configurations (simplified)

 - de_engine (DE , €)
      + de - products
      
 - en_engine (EN , £)
      + en -products

Given the case you would like to offer both currencies in both languages, you will need four engines!

 - de_eur_engine (DE , €)
      + de-eur - products
      
 - en_eur_engine (EN , €)
      + en-eur -products
      
 - de_pound_engine (DE , £)
      + de_pound - products
      
 - en__pound engine (EN , £)
      + en_pound -products      

Keep this in mind, but apparently that's how doofinder is designed.

Note before you continue reading, I'm aware that there is some potential in mixing up terminology, because of the following:

  • in doofinder:
    • an engine is just a search engine with any number of types (indices) attached.
  • in this bundle:
    • an engine refers to exactly one engine and one type.

This is due to design and let's us determine an engine and type specific representation per Object. This is important, you can read more on this in the internals.

Some Example Configuration

Below you can see a configuration we have been using for a project. We are using 3 types for one search engine. So each bundle-engine here uses the same but references different types.

  • products with type: test_products
  • products_special with type: test_products_special
  • content with type: test_content

way more interesting are the engine's item definitions. class defines the object's classname it's "listening" to, the field set defines the feed representation.

  • dfAttribute: is the attribute's name obviously (this will end up in feeds header line)
  • classAttribute: either:
    • 'self' with combination of a merger
    • the attributes Name. e.g 'description' - we are using PathProperty and Reflection to retrieve the value
  • merger: originally designed to merge arrays, but can be used to do other things as well. just use it as a callback where you can control the output. see here for more details
  • locale: very useful if the classAttribute is a localized field
  • getter: if classAttribute itself is another object, then getter will be executed.

This settings and behavior came up during development, so there is still potential to do this better and more user friendly. Configuration can be quite redundant right now for example.

doo_finder:
        search_api_key: "<search-api-key>"
        management_api_key: "<management-api-key>"
    search_engines:
       engine:
            name: "products"
            type: "test_product"
            site_url: "https://example.de/"
            language: "German"
            currency: "Euro"
            hashId: "<hashId>"
            baseURL: "https://example.de"
            user: ~
            item:
                class: "AppBundle\\Model\\DefaultProduct"
                listing: "Pimcore\\Model\\DataObject\\Product\\Listing"
                fields:
                    -  {dfAttribute: "title", classAttribute: "self", merger: [ { class: "AppBundle\\doofinder\\TitleMerger", field: "", options: [{ locale: "de" } ] } ] }
                    -  {dfAttribute: "description", classAttribute: "description", merger: [ { class: "AppBundle\\doofinder\\DescriptionMerger", field: "", options: [{ locale: "de" } ] } ] }
                    -  {dfAttribute: "image link", classAttribute: "self", locale: "de", merger: [ { class: "AppBundle\\doofinder\\FirstImageMerger", field: "", options: [{ locale: "de", baseUrl: "https://example.de" , thumbnail: 'productDetailThumb'}] } ] }
                    -  {dfAttribute: "product_type", classAttribute: "categories", locale: "de", merger: [ { class: "AppBundle\\doofinder\\CategoriesMerger", field: "", options: [{locale: "de"}] } ] }
                    -  {dfAttribute: "link",  url: [ { class: "AppBundle\\doofinder\\DefaultProductURLProvider", locale: "de", route: "shop-detail" } ] }
                    -  {dfAttribute: "attributes", classAttribute: "self", locale: "de", merger: [ { class: "AppBundle\\doofinder\\DefaultProductAttributeMerger", field: "", options: [{"locale":"de"} ]} ] }
                    -  {dfAttribute: "price",  classAttribute: "self", merger: [ { class: "AppBundle\\doofinder\\PriceMerger", field: "", options: [{ locale: "de" } ] } ] }
                    -  {dfAttribute: "uvp price",  classAttribute: "self", merger: [ { class: "AppBundle\\doofinder\\UvpPriceMerger", field: "", options: [{ locale: "de"} ] } ] }
                    -  {dfAttribute: "id", classAttribute: "id"}
                    -  {dfAttribute: "brand", classAttribute: "brand", locale: "de" , getter: "getName" }
                    -  {dfAttribute: "sku_field", classAttribute: "sku" }
                    -  {dfAttribute: "sku2", classAttribute: "skuTwo" }
                    -  {dfAttribute: "sku3", classAttribute: "skuThree",}
                    -  {dfAttribute: "manufacturer", classAttribute: "manufacturer", locale: "de", getter: "getName" }

       engine_product_special:
            name: "products_special"
            type: "test_product_special"
            site_url: "https://example.de/"
            language: "German"
            currency: "Euro"
            hashId: "<hashId>"
            baseURL: "https://example.de"
            user: ~
            item:
                class: "AppBundle\\Model\\DefaultProductSpecial"
                listing: "Pimcore\\Model\\DataObject\\Product\\Listing"
                fields:
                    -  {dfAttribute: "title", classAttribute: "name", locale: "de"  }
                    -  {dfAttribute: "description", classAttribute: "description", merger: [ { class: "AppBundle\\doofinder\\DescriptionMerger", field: "", options: [{ locale: "de" } ] } ] }
                    -  {dfAttribute: "image_link", classAttribute: "self", locale: "de", merger: [ { class: "AppBundle\\doofinder\\SpecialImageMerger", field: "", options: [{ baseUrl: "https://example.de" , thumbnail: 'specialProductThumbnail'}] } ] }
                    -  {dfAttribute: "product type", classAttribute: "categories", locale: "de", merger: [ { class: "AppBundle\\doofinder\\CategoriesMerger", field: "", options: [{locale: "de"}] } ] }
                    -  {dfAttribute: "link",  url: [ { class: "AppBundle\\doofinder\\ProductSpecialURLProvider", locale: "de", route: "shop-detail" , prefix: "https://example.de" } ] }
                    -  {dfAttribute: "id", classAttribute: "id"}

       engine_content:
                name: "content"
                type: "test_content"
                site_url: "https://example.de/"
                language: "German"
                currency: "Euro"
                hashId: "<hashId>"
                baseURL: "https://example.de"
                user: ~
                item:
                    class: "\\Pimcore\\Model\\Document"
                    listing: "\\Pimcore\\Model\\Document\\Listing"
                    listing_arguments: [unpublished: "false", condition: "`parentId` = 2"]
                    fields:
                        -  {dfAttribute: "id", classAttribute: "id"  }
                        -  {dfAttribute: "title", classAttribute: "title", locale: "de"  }
                        -  {dfAttribute: "description", classAttribute: "description", locale: "de"  }
                        -  {dfAttribute: "metadata", classAttribute: "metadata", locale: "de",merger: [ { class: "AppBundle\\doofinder\\MetadataMerger"} ] }
                        -  {dfAttribute: "link",  url: [ { class: "AppBundle\\doofinder\\DocumentURLProvider", prefix: "https://example.de" } ] }
                        #-  {dfAttribute: "image_link", classAttribute: "self", locale: "de", merger: [ { class: "AppBundle\\doofinder\\ContentImageMerger", field: "", options: [{  baseUrl: "https://example.de"  }] } ] }
                        #-  {dfAttribute: "content", classAttribute: "self", merger: [ { class: "AppBundle\\doofinder\\PageContentMerger" } ] }


What's next?

After defining your configuration, to generate your datafeed you will need to define a pimcore/symfony command to do the heavy lifting for you.

If you are familiar with Pimcore you will know that you have multiple possibilities to query for objects

  • use Listings via the API
  • write your own SQL query
  • using an Index

You can find a implementation of such a command here, which uses both default object listings and AdvancedMysql Index Service and runs with efficient ressource management in mind.

More Details

TODO

  • explain active and objectPathRegex configuration

doofinder's People

Contributors

asioso avatar

Stargazers

 avatar

Watchers

 avatar

Forkers

sigwinhq

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.