简体   繁体   English

Elasticsearch:对嵌套字段的多重匹配查询

[英]Elasticsearch : Multi match query on nested fields

I am having a problem with multi-match query in RoR. 我在RoR中遇到多匹配查询问题。 I have Elastic Search configured and working however I am working on setting up aggregations which so far seem to work, but for whatever reason I am not able to search on the field which I am aggregating. 我已经配置了Elastic Search并正在工作,但是我正在设置到目前为止似乎有效的聚合,但是由于某种原因,我无法在正在聚合的字段上进行搜索。 This is the extract from my model: 这是我的模型的摘录:

    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

I am able to search on all fields as specified in the multi_match_query apart of "occasion_name" which happens to be the field I am aggregating. 我可以在multi_match_query中指定的所有字段中搜索“ occasion_name”(恰好是我正在汇总的字段)。 I have checked that the field is correctly indexed (using elastic search-head plugin). 我检查了该字段是否已正确索引(使用弹性搜索头插件)。 I am also able to display the facets with the aggregated occasion_names in my view. 我还可以在视图中显示带有汇总的case_name的构面。 I tried everything I can think of, including removing the aggregation and searching on occasion_name, but still no luck. 我尝试了我能想到的所有方法,包括删除聚合和在case_name上搜索,但还是没有运气。 (I am using the elasticsearch-rails gem) (我正在使用elasticsearch-rails gem)

Any help will be much appreciated. 任何帮助都感激不尽。

Edit: 编辑:

I got this ES query from rails: 我从rails得到这个ES查询:

@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}}}}}}},

This is an example of all that gets indexed for 1 of my dummy recipes I use for testing (the contents are meaningless - I use this only for testing): 这是所有用于测试的我的虚拟配方之一的索引的示例(内容无意义-我仅将其用于测试):

{
"_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: 编辑2:

I managed to make the search work for occasions as suggested by @rahulroc, but now I can't search on anything else... 我设法按@rahulroc的建议进行搜索,但是现在我无法搜索其他任何东西了……

    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: Adding multiple nested fields - I am trying to add the rest of my aggregations but I am facing similar problem as before. 更新:添加多个嵌套字段 -我正在尝试添加其余的聚合,但是我面临与以前类似的问题。 My end goal will be to use the aggregations as filters so I need to add about 4 more nested fields to my query (I also would like to have the fields searchable) Here is the working query as provided by @rahulroc + the addition of another nested field which I can't search on. 我的最终目标是将聚合用作过滤器,因此我需要在查询中添加大约4个嵌套字段(我也想使字段可搜索)这是@rahulroc提供的有效查询+另外一个无法搜索的嵌套字段。 As before in terms of indexing everything is working and I can display the aggregations for the newly added field, but I can't search on it. 与以前一样,在建立索引方面,一切都可以正常工作,我可以显示新添加字段的汇总,但无法对其进行搜索。 I tried different variations of this query but I couldn't make it work (the rest of the fields are still working and searchable - the problem is just the new field): 我尝试了此查询的其他变体,但无法使其正常工作(其余字段仍在工作且可搜索-问题只是新字段):

 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

You need to create a separate nested clause for matching a nested field 您需要创建一个单独的嵌套子句以匹配嵌套字段

"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"]                }
            }
        ]
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM