2016-03-28 10 views
2

Ich habe ein Problem mit Multi-Match-Abfrage in RoR. Ich habe Elastic Search konfiguriert und funktioniert, aber ich arbeite an der Einrichtung von Aggregationen, die bisher funktionieren, aber aus welchen Gründen auch immer bin ich nicht in der Lage, auf dem Feld zu suchen, das ich aggregiere. Dies ist der Auszug aus meinem Modell:Elasticsearch: Multi-Match-Abfrage für verschachtelte Felder

settings :index => { :number_of_shards => 1 } do 
     mapping do 
      indexes :id, index: :not_analyzed 
      indexes :name 
      indexes :summary 
      indexes :description 

      indexes :occasions, type: 'nested' do 
      indexes :id, type: 'integer' 
      indexes :occasion_name, type: 'string', index: :not_analyzed 

      ... 

      end 
     end 
     end 




    def as_indexed_json(options = {}) 
    self.as_json(only: [:id, :name, :summary, :description], 
       include: { 
        occasions:   { only: [:id, :occasion_name] }, 
        courses:    { only: [:id, :course_name] }, 
        allergens:   { only: [:id, :allergen_name] }, 
        cookingtechniques: { only: [:id, :name] }, 
        cuisine:    { only: [:id, :cuisine_name]} 
       }) 
    end 


class << self 
    def custom_search(query) 
     __elasticsearch__.search(query: multi_match_query(query), aggs: aggregations) 
    end 


    def multi_match_query(query) 
     { 
      multi_match: 
      { 
       query: query, 
       type: "best_fields", 
       fields: ["name^9", "summary^8", "cuisine_name^7", "description^6", "occasion_name^6", "course_name^6", "cookingtechniques.name^5"], 
       operator: "and" 
      } 
     } 
    end 

Ich bin in der Lage auf allen Feldern zu suchen, wie in der multi_match_query abgesehen von „occasion_name“ festgelegt, die das Feld passiert sein ich bin aggregieren. Ich habe überprüft, dass das Feld korrekt indiziert ist (mit elastischem Suchkopf-Plugin). Ich bin auch in der Lage, die Facetten mit den aggregierten occasion_names in meiner Ansicht anzuzeigen. Ich habe alles ausprobiert, was ich mir vorstellen kann, einschließlich das Entfernen der Aggregation und die Suche bei Gelegenheit, aber immer noch kein Glück. (ich benutze die elasticsearch-rails gem)

Jede Hilfe wird sehr geschätzt.

Edit:

Ich habe ES diese Abfrage von Schienen:

@search= 
    #<Elasticsearch::Model::Searching::SearchRequest:0x007f91244df460 
    @definition= 
    {:index=>"recipes", 
    :type=>"recipe", 
    :body=> 
     {:query=> 
     {:multi_match=> 
      {:query=>"Christmas", 
      :type=>"best_fields", 
      :fields=>["name^9", "summary^8", "cuisine_name^7", "description^6", "occasion_name^6", "course_name^6", "cookingtechniques.name^5"], 
      :operator=>"and"}}, 
     :aggs=> 
     {:occasion_aggregation=> 
      {:nested=>{:path=>"occasions"}, :aggs=>{:id_and_name=>{:terms=>{:script=>"doc['occasions.id'].value + '|' + doc['occasions.occasion_name'].join(' ')", :size=>35}}}}}}}, 

Dies ist ein Beispiel für alles, was ich zum Testen verwende für 1 meine Dummy-Rezepte indiziert wird (der Inhalt bedeutungslos ist - ich benutze dies nur zum Testen):

{ 
"_index": "recipes", 
"_type": "recipe", 
"_id": "7", 
"_version": 1, 
"_score": 1, 
"_source": { 
"id": 7, 
"name": "Mustard-stuffed chicken", 
"summary": "This is so good we'd be surprised if this chicken fillet recipe doesn't become a firm favourite. Save it to your My Good Food collection and enjoy", 
"description": "Heat oven to 200C/fan 180C/gas 6. Mix the cheeses and mustard together. Cut a slit into the side of each chicken breast, then stuff with the mustard mixture. Wrap each stuffed chicken breast with 2 bacon rashers – not too tightly, but enough to hold the chicken together. Season, place on a baking sheet and roast for 20-25 mins.", 
"occasions": [ 
{ 
"id": 9, 
"occasion_name": "Christmas" 
} 
, 
{ 
"id": 7, 
"occasion_name": "Halloween" 
} 
, 
{ 
"id": 8, 
"occasion_name": "Bonfire Night" 
} 
, 
{ 
"id": 10, 
"occasion_name": "New Year" 
} 
], 
"courses": [ 
{ 
"id": 9, 
"course_name": "Side Dish" 
} 
, 
{ 
"id": 7, 
"course_name": "Poultry" 
} 
, 
{ 
"id": 8, 
"course_name": "Salad" 
} 
, 
{ 
"id": 10, 
"course_name": "Soup" 
} 
], 
"allergens": [ 
{ 
"id": 6, 
"allergen_name": "Soya" 
} 
, 
{ 
"id": 7, 
"allergen_name": "Nut" 
} 
, 
{ 
"id": 8, 
"allergen_name": "Other" 
} 
, 
{ 
"id": 1, 
"allergen_name": "Dairy" 
} 
], 
"cookingtechniques": [ 
{ 
"id": 15, 
"name": "Browning" 
} 
], 
"cuisine": { 
"id": 1, 
"cuisine_name": "African" 
} 
} 
} 

EDIT 2:

I m anaged auf die Suche nach Gelegenheiten zu machen, wie @rahulroc vorgeschlagen, aber jetzt kann ich nicht anders auf irgendetwas suchen ...

def multi_match_query(query) 
    { 
     nested:{ 
      path: 'occasions', 
      query:{ 
     multi_match: 
     { 
      query: query, 
      type: "best_fields", 
      fields: ["name^9", "summary^8", "cuisine_name^7", "description^6", "occasion_name^6", "course_name^6", "cookingtechniques.name^5"], 
      operator: "and" 
     } 
    } 

     } 
    } 
end 

UPDATE: Hinzufügen mehr verschachtelten Felder - Ich versuche, den Rest hinzufügen meiner Aggregationen, aber ich stehe vor ähnlichen Problemen wie zuvor. Mein Endziel wird sein, die Aggregationen als Filter zu verwenden, also muss ich noch 4 verschachtelte Felder zu meiner Abfrage hinzufügen (ich möchte auch, dass die Felder durchsuchbar sind). Hier ist die Arbeitsabfrage, wie sie von @rahulroc + zur Verfügung gestellt wird verschachteltes Feld, nach dem ich nicht suchen kann. Wie zuvor bei der Indizierung funktioniert alles und ich kann die Aggregationen für das neu hinzugefügte Feld anzeigen, aber ich kann nicht danach suchen. Ich habe versucht, verschiedene Variationen dieser Abfrage, aber ich konnte es nicht machen (die restlichen Felder sind noch arbeiten und durchsuchbar - das Problem nur das neue Feld ist):

def multi_match_query(query) 
     { 

     bool: { 
      should: [ 
       { 
        nested:{ 
         path: 'occasions', 
         query: { 
          multi_match: 
          { 
             query: query, 
             type: "best_fields", 
             fields: ["occasion_name"] 

            } 
         } 
        } 
       }, 

       { 
        nested:{ 
         path: 'courses', 
         query: { 
          multi_match: 
           { 
            query: query, 
            type: "best_fields", 
            fields: ["course_name"] 

           } 
         } 
        } 
       }, 

       { 
        multi_match: { 
         query: query, 
         fields:["name^9", "summary^8", "cuisine_name^7", "description^6"], 

        } 
       } 
      ] 
     } 


     } 
    end 
+0

Ich bin nicht vertraut mit Schienen, aber habe einige ES-Erfahrung. Können Sie die JSON-Abfrage anzeigen, die an ElasticSearch gesendet wird? – Cfreak

+0

Hallo, ich bearbeite gerade meinen ersten Beitrag - ich habe die Abfrage eingefügt. Danke – martini

+0

occasion_name ist ein verschachteltes Feld. Es kann nicht direkt in Matchabfrage – Rahul

Antwort

3

Sie benötigen eine separate verschachtelte erstellen Klausel zum Abgleichen eines verschachtelten Felds

"query": { 
    "bool": { 
     "should": [ 
      { 
       "nested": { 
        "path": "occassions", 
        "query": { 
         "multi_match": { 
          "query": "Christmas", 
          "fields": ["occassion_name^2"] 
         } 
        } 
       } 
      }, 
      { 
       "multi_match": { 
        "query": "Christmas", 
        "fields":["name^9", "summary^8", "cuisine_name^7", "description^6","course_name^6"]    } 
      } 
     ] 
    } 
} 
+0

zugegriffen werden Danke für den Vorschlag, ich habe es geschafft, die Suche für Gelegenheiten wie bearbeiten 2, aber jetzt kann ich nichts anderes suchen – martini

+0

Die anderen Felder gehören nicht zum verschachtelten Bereich von Gelegenheiten. Andere Felder müssen in ihrem jeweiligen Umfang liegen. Machen Sie separate Klauseln in der bool-sollte-Klausel. Ich werde die vollständige Abfrage in einiger Zeit bereitstellen. – Rahul

+0

Ich habe die Antwort mit der vollständigen Abfrage aktualisiert – Rahul

Verwandte Themen