2015-09-05 10 views
6

私はElasticSearchのわずか数日しか経っていません。学習の練習として、いくつかのジョブリストサイトからジョブを集計し、私と一緒に遊ぶために。ElasticSearch内のフィルタリングされたネストされたinner_hitsクエリの集約

私のインデックスには、ジョブをリストする各Webサイトのドキュメントが含まれています。これらのドキュメントのそれぞれのプロパティは 'jobs'配列です。この配列には、そのサイトに存在する各ジョブのオブジェクトが含まれています。私はElasticSearchのinner_hitsとネストされた機能を使用して、私がやりたいことを達成できるかどうかを確認しようとしています。 。

一致するジョブのみを照会、フィルタリング、および戻すことができます。しかし、同じinner_hits制約を集約に適用する方法がわかりません。

これが私のマッピングです:

{ 
    "jobsitesIdx" : { 
    "mappings" : { 
     "sites" : { 
     "properties" : { 
      "createdAt" : { 
      "type" : "date", 
      "format" : "dateOptionalTime" 
      }, 
      "jobs" : { 
      "type" : "nested", 
      "properties" : { 
       "company" : { 
       "type" : "string" 
       }, 
       "engagement" : { 
       "type" : "string" 
       }, 
       "link" : { 
       "type" : "string", 
       "index" : "not_analyzed" 
       }, 
       "location" : { 
       "type" : "string", 
       "fields" : { 
        "raw" : { 
        "type" : "string", 
        "index" : "not_analyzed" 
        } 
       } 
       }, 
       "title" : { 
       "type" : "string" 
       } 
      } 
      }, 
      "jobscount" : { 
      "type" : "long" 
      }, 
      "sitename" : { 
      "type" : "string" 
      }, 
      "url" : { 
      "type" : "string" 
      } 
     } 
     } 
    } 
    } 
} 

これは私が(Node.jsのから)しようとしているクエリや集合体である:

client.search({ 
    "index": 'jobsitesIdx, 
    "type": 'sites', 
    "body": { 


    "aggs" : { 
      "jobs" : { 
       "nested" : { 
        "path" : "jobs" 
       }, 
       "aggs" : { 
        "location" : { "terms" : { "field" : "jobs.location.raw", "size": 25 } }, 
        "company" : { "terms" : { "field" : "jobs.company.raw", "size": 25 } } 
       } 
      } 
     }, 


    "query": { 
     "filtered": { 
      "query": {"match_all": {}}, 
      "filter": { 
      "nested": { 
       "inner_hits" : { "size": 1000 }, 
       "path": "jobs", 
       "query":{ 
       "filtered": { 
        "query": { "match_all": {}}, 
        "filter": { 
        "and": [ 
         {"term": {"jobs.location": "york"}}, 
         {"term": {"jobs.location": "new"}} 
        ] 
        } 
       } 
       } 
      } 
      } 
     } 
     } 
    } 
}, function (error, response) { 
    response.hits.hits.forEach(function(jobsite) { 
    jobs = jobsite.inner_hits.jobs.hits.hits; 

    jobs.forEach(function(job) { 
     console.log(job); 
    }); 

}); 

    console.log(response.aggregations.jobs.location.buckets); 
}); 

これは私に新しい内のすべてのジョブinner_hitsをバック与えますヨークですが、集計では、inner_hitsと一致するものだけでなく、すべての場所や会社の数がわかります。

一致するinner_hitsに含まれるデータにのみ集計を取得する方法に関する提案はありますか?

編集: 私はこれを更新して、要求に応じてマッピングデータとインデックスデータをエクスポートします。私はここで見つけるこの使用Taskrabbitのelasticdumpツール、エクスポート: https://github.com/taskrabbit/elasticsearch-dump

をインデックス:http://pastebin.com/WaZwBwn4 マッピング:http://pastebin.com/ZkGnYN94

インデックスがjobsites6命名されたという点で、上記のリンクされたデータは、私の元の質問には、サンプルコードとは異なり質問で言及されているjobsitesIdxの代わりにデータにまた、データの型は 'job'ですが、上のコードでは 'sites'です。

上記のコードでコールバックを入力して、応答データを表示しました。私はそれを見ることができ、私のinner_hitsはニューヨークのものに限定されているので

[ { key: 'New York, NY', doc_count: 243 }, 
    { key: 'San Francisco, CA', doc_count: 92 }, 
    { key: 'Chicago, IL', doc_count: 43 }, 
    { key: 'Boston, MA', doc_count: 39 }, 
    { key: 'Berlin, Germany', doc_count: 22 }, 
    { key: 'Seattle, WA', doc_count: 22 }, 
    { key: 'Los Angeles, CA', doc_count: 20 }, 
    { key: 'Austin, TX', doc_count: 18 }, 
    { key: 'Anywhere', doc_count: 16 }, 
    { key: 'Cupertino, CA', doc_count: 15 }, 
    { key: 'Washington D.C.', doc_count: 14 }, 
    { key: 'United States', doc_count: 11 }, 
    { key: 'Atlanta, GA', doc_count: 10 }, 
    { key: 'London, UK', doc_count: 10 }, 
    { key: 'Ulm, Deutschland', doc_count: 10 }, 
    { key: 'Riverton, UT', doc_count: 9 }, 
    { key: 'San Diego, CA', doc_count: 9 }, 
    { key: 'Charlotte, NC', doc_count: 8 }, 
    { key: 'Irvine, CA', doc_count: 8 }, 
    { key: 'London', doc_count: 8 }, 
    { key: 'San Mateo, CA', doc_count: 8 }, 
    { key: 'Boulder, CO', doc_count: 7 }, 
    { key: 'Houston, TX', doc_count: 7 }, 
    { key: 'Palo Alto, CA', doc_count: 7 }, 
    { key: 'Sydney, Australia', doc_count: 7 } ] 

:私は、しかし、私は場所のため、この凝集を見ています、予想通り、inner_hitsのforeachループからニューヨークのジョブのみを見ています集約は私のinner_hitsにはありません。なぜなら、それはすべての場所の数をカウントしているからです。

+0

いくつかの例のデータを提供できますか(要点など)?あなたが返すと期待している結果は? –

答えて

10

これは、ニューヨークのジョブだけを含むように集約に同じフィルタを追加することで実現できます。 また、2番目の集計ではcompany.rawでしたが、マッピングではjobs.companyフィールドにはという名前のnot_analyzedという名前の部分がないため、解析されていない会社名に集約する場合は、追加する必要があります。

{ 
    "_source": [ 
    "sitename" 
    ], 
    "query": { 
    "filtered": { 
     "filter": { 
     "nested": { 
      "inner_hits": { 
      "size": 1000 
      }, 
      "path": "jobs", 
      "query": { 
      "filtered": { 
       "filter": { 
       "terms": { 
        "jobs.location": [ 
        "new", 
        "york" 
        ] 
       } 
       } 
      } 
      } 
     } 
     } 
    } 
    }, 
    "aggs": { 
    "jobs": { 
     "nested": { 
     "path": "jobs" 
     }, 
     "aggs": { 
     "only_loc": { 
      "filter": {   <----- add this filter 
      "terms": { 
       "jobs.location": [ 
       "new", 
       "york" 
       ] 
      } 
      }, 
      "aggs": { 
      "location": { 
       "terms": { 
       "field": "jobs.location.raw", 
       "size": 25 
       } 
      }, 
      "company": { 
       "terms": { 
       "field": "jobs.company", 
       "size": 25 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
} 
+0

私はこれが動作することを確認しました、ありがとう!私が理解しているように、 'クエリ'によって返された親ドキュメントは、集約の範囲に影響します。 ESがinner_hitsに関して適用することを可能にした場合、aggsでフィルタの制約を再度繰り返さなくてもいいでしょう。一方、 'experimental' inner_hits機能を使用していると、問題を抱えている可能性があります。また、私は自分がインデックスを再作成したときにjobs.company.rawを追加するというメモを持っていました。良いキャッチです。 – mmccaff

関連する問題