guide
  • Introduction
  • Guiding Principles
    • Mission Statement
    • Conflict Resolution Process
  • Operating Model
    • Working Together
    • Holacracy
      • Meetings
      • Specific Roles
      • Terms and Definitions
      • Finer Points
      • Holacracy-Asana Key
    • Getting Things Done
      • Daily, Weekly, Monthly, and Annual Reviews
      • GTD-Asana Key
    • Transparency
    • Language
    • Budgeting
    • By Department
      • Engineering Operations
  • General Guidelines
  • Employment Policies
    • Equal Opportunity Employment
    • At-Will Employment
    • Code of Conduct in the Community
    • Complaint Policy
    • Drug and Alcohol Policy
    • Vacation, Holiday, and Paid Time Off (PTO) Policy
    • Supplemental Policies for Remote Employees and Contractors
    • Supplemental Policy for Bonus, Commissions, and other Performance-based Payments
    • Supplemental Policies for Hourly International Contractors or Workers
    • Supplemental Policies for Hourly International Contractors or Workers
    • Disputes and Arbitration
  • Benefits and Perks
    • Health Care
    • Vacation, Holiday and Paid Time Off (PTO) Policy
    • Holiday List
  • Hiring Documents
    • Acknowledgement of Receipt
    • Partner Proprietary Information and Inventions Agreement
  • Engineering Wiki
    • Code Snippets
      • Front End Code Snippets
    • Setup
      • 1: Overview of development using Audienti
      • 2: How to setup your dev environment on Docker
      • 2a: Setting up on our cloud your dev server
      • 3: Connect to Production using the VPN
      • 4: Import data into your development environment
    • Deployment
      • Docker based deployment of back end (manual)
    • Culture
      • How our development team works
      • Code Best Practices
    • Tips
      • Setting up a new development machine
      • Importing data to Development environment
      • GIT workflow and work tracking
      • Using Slack
      • Using Rubocop
      • Our Code Standards
      • General suggested best practices
      • Tracking your time
      • Naming Iterations
    • Migrations
      • Postgres
      • ElasticSearch
      • Redis
    • Database and System Maintenance
      • Redis Howtos
      • Elasticsearch HowTos
      • Postgres HowTos
      • Administration recipes
      • App maintenance crash course notes
    • Front End
      • 2016 Plan
      • Deploy
      • Assets
      • SearchLogic
      • How to create UI components
      • OMA Standard Tables
    • Monitoring and Alerting
      • Monitoring Systems
      • Monitoring individual controller actions
      • Get notified when a metric reaches a certain threshold
      • Instrumenting your models using Oma Stats
      • Configuring Graphite Charts
      • Tracking your results with StatsD
      • Logging Fields
      • Updating Kibana Filtering
    • Testing
      • Coverage
      • Elasticsearch mapping config synchronization
      • Testing Gotchas
      • Rspec Preloader
      • Test Best Practices
    • Models
      • Backlinks
    • Queueing and Worker System
      • Queueing and Job Overview
    • Processors
      • Rebuilding Spot Instances
      • Deploying processors
      • Running processors in development
      • Reverting to the previous build on a failed deployment
    • Processors / Opportunity Pipeline
      • Opportunity Pipeline
      • Diagram
    • Processors / Enrichment Pipeline
      • Diagram
      • Clustering
    • Processors / Backlink Pipeline
      • Diagram
      • Backlink Pipeline external APIs
      • Backlink pipeline logic
    • Processors / Automation Pipeline
      • Diagram
      • Automation Pipeline Overview
      • Agents
      • Running in development
    • Messaging and Social Accounts
      • Overview
    • API
      • Audienti API
    • Algorithms
    • Troubleshooting
      • Elasticsearch
    • Big Data Pipeline Stuff
      • Spark
    • Our Product
      • Feature synopsis of our product
    • Research
      • Backend framework comparison
      • Internet marketing Saas companies
    • Code snippets
      • Commonly Used
      • Not Used
    • Miscellaneous
      • Proxies and Bax
    • Legacy & Deprecated
      • Search criteria component
      • Classes list
      • Target Timeline
      • Twitter processor
      • Asset compilation
      • Test related information
      • Interface to EMR Hadoop jobs
      • Mongo Dex Indexes to be Built
      • Mongodb errors
      • Opportunity pipeline scoring
      • Graph Page
      • Lead scoring
      • Insights
      • Shard keys
      • Setting up OMA on local
      • Clone project to local machine
      • Getting around our servers in AWS
  • Acknowledgements
  • Documents That Receiving Your First Payment Triggers Acknowledgement and Acceptanace
Powered by GitBook
On this page
  • Example of usage
  • Pseudo-filters (eXtended)
  • Some terminological details
  • query
  • search
  • tree
  • Already implemented filters and TODO
  • FAQ
  1. Engineering Wiki
  2. Front End

SearchLogic

Example of usage

In controller

# Create an instance of search logic.
# It assume that params[:q] (by default) contains a json string,
# that represents a query state tree.
@search = SearchLogic.mentions params: params

# Extract 'keyword_ids' from the search logic tree.
# Since Mention ES class doesn't have 'keyword_ids' attribute,
# we should use 'xterms_values' (eXtended term values)
# and remove the values BEFORE a "real" query json for ES is built.
keyword_ids = @search.xterms_values('keyword_ids')
wordsmaster_ids = Keyword.where(id: keyword_ids).map(&:wordsmaster_id).uniq

# Specify a terms filter for 'wordsmaster_id'.
# Note, #with_terms_values return a new search logic instance.
# It allows as to use the previous instance (@search) in views
# generating links. And at the same time we use the new instance
# to "enhance" it with facets and filters and do actual requests
# to Elasticsearch.
search = @search.with_terms_values 'wordsmaster_id', wordsmaster_ids

# Add facets. Note, added facets will not affect @search instance.
query = ::SearchLogic::Facets.new(search.query).
  add_facet('sources', "terms" => {"field" => 'source'})
  query

# Do request Elasticsearch
@search_response = Connectors::Elasticsearch.client_search(
  Mention.index_name,
  query
)

In view

<%# Generate a link for a similar page, but the page will not contain "twitter" related results. %>
<%= link_to 'without twitter results',
             project_volume_index_path(@project, 
                                       search.without_terms_value("source", 'twitter').url_params) %
>

Pseudo-filters (eXtended)

In a degenerate case the search logic query tree might be a valid Elasticsearch request body. But in more general cases it contains pseudo-filters, what is not valid parts of Elasticsearch query DSL.

To turn 'search' to 'query' one must process pseudo-filters. For example talking about Mention, "keyword tags" pseudo-filter must be removed and at the same time 'wordsmaster id' terms filter should be added/modified to represent "keyword tags" values.

Each pseudo-filter represents a "virtual" filter what presents only in UI and should be somehow transformed in "real" Elasticsearch filter.

See the example section above for an additional example of pseudo-filters for 'keyword_ids'.

Some terminological details

query

'query' is a hash representation of a valid ES request body. Cannot contain pseudo-filters.

search

'search' is an instance of 'search logic' tree. Might contain pseudo-filters.

tree

A low level API to manipulate tree structure. Should not be directly exposed to client code.

Already implemented filters and TODO

SearchLogic has:

  • terms_filter

  • xterms_filter

  • range_filter

It assumes, we is going to add additional filter kinds as we need them.

FAQ

Q: Were there any thoughts on how to apply pseudo filters to the ES results in a generic way?

A: There is no generic way to deal with pseudo filters (at least at the moment).

Q: Do we know what the possible pseudo filters are at this point at all, or was this not explored at all?

A: A search logic tree is just a Ruby hash or a JSON string. So, you can freely recognize a pseudo filter by its "x-" prefix. For example for a xTerms filter a key in a ruby hash will be "x-terms".

Q: Does the view (url, whatever) pass explicit information on what type of ES query we are going to make, or is the query type somehow inferred from all the other params passed in?

A: The whole page state should be stored in the 'q' URL param. Thus in a near future the search logic tree will contain "page" key to deal with pagination. There is a subtle point here: how to work with Postgres or Redis related part of state. Currently SearchLogic ignores the problem.

Q: Let's say you would do a range filter in ES. would you have that in the url explicitly or would you just use 'from' and 'to' and the SearchLogic would infer that it needs to make a range filter?

A: A search logic tree should be as closed to a valid ES query tree as possible. So, if your case allows to have "hardcoded" range boundaries, you should just use it as is:search.with_range_value "created_at", 'gte', "now-1d". But if you particular case requires to re-compute the range boundaries each time, you will add "x-range" filter kind and will use it.

PreviousAssetsNextHow to create UI components

Last updated 7 years ago