2017-01-13 6 views
0

職場では、これ以上存在しない人が作成したスクリプトがあります。このように見ているノードを持つXMLファイルを取得するために使用されます。Perlを使用してElasticSearchクエリを動的に変更します

<query maxresults='15000'> 
     <![CDATA[                   
     and(                   
       isavailable:1,         
       not(designation:string("test wine", mode="or")),     
       visibility:10,             
       bestprice:>0               
     )                    
     ]]> 
    </query> 

我々はこのためにPerlを使用しています。目標は、ノード内に含まれるFAST要求を修正して、いくつかのパラメータを動的に追加する(例えば、 "maxresults"属性を用いて結果を制限する)ことである。コードのこの部分は機能しますが、ElasticSearchに切り替えるので、コードを変更して動作させる必要があります。

問題は、PerlでElasticSearchクエリを変更する信頼できる方法が見つからないということです。これまでのところ私はこれでした:

use strict; 
use warnings; 
use JSON; 
use Data::Dumper; 
use Search::Elasticsearch; 

my $json = 
'{"query": 
    {"bool": 
     {"must": 
      [ 
      {"term": 
       {"isavailable":"1"} 
      }, 
      {"term": 
       {"visibility":"10"} 
      }, 
      {"range": 
       {"bestprice": 
        {"gt":"0"} 
       } 
      } 

      ], 
     "must_not": 
      [{"regexp": 
       {"designation":"[Tt]+[Ee]+[Ss]+[Tt]+"} 
      }, 
      {"regexp": 
       {"designation":"[Ww]+[Ii]+[Ne]+[Ee]+"} 
      } 
      ] 
     } 
    } 
}'; 

my $result = decode_json($json); 

をしかし、それは私に、ハッシュの代わりに、オブジェクトを与え、私は動的にちょうど(例えば)追加するには、このハッシュを変更しようと頭痛を取得しています:

{"regexp": {"designation":"[Ff]+[Oo]+"}} 

を「must_not」オブジェクト内の配列に追加します。

私はこれを実行しようとしました:

my %must = (must_not => [{"regexp" => 
             {"designation" => "[Ff]+[Oo]+"} 
          } 
          ]); 


$result{"query"} = \%must; 

print keys(%{$result{query}}); 

しかし、これは単に%と、全ノードのコンテンツはハッシュしなければならないと私はそれを正しく追加する方法を見つけることができません置き換えられます。私はmust_notオブジェクトに含まれている配列の内部でハッシュをプッシュしようとしましたが、エラーが発生するだけです。

私は本当にこの状況に困惑しています。特に、私は本当にPerlのエキスパートではないので、どんな助けも歓迎すべきものではありません。

ありがとうございます!

+0

JSONから何かを変換すると、プレーンなデータ構造になります。デフォルトでPerlにはオブジェクトはありません。あなたはデータ構造を変更する必要があります、それは正しいです。あなたは完全に行かなければならない、またはそれが置き換えられる、それは正しい。 – simbabque

答えて

2

Perlはデフォルトでオブジェクトを処理しないため、オブジェクトではありません。オブジェクトが必要な場合は、クラスを作成してインスタンス化する必要があります。しかし、decode_jsonそれを行うことはできません。それが行うのは、複雑なデータ構造を返すことだけです。

そのデータ構造内のフィルタを保持する配列refに別のエントリを追加するには、pushが必要です。そのためには、pushは参照を操作したくないので、配列refを逆参照する必要があります。 Perlは次の構文であなたのために正しいことを行います。

# this dereferences the array ref for push 
# |          | 
push @{ $result->{query}->{bool}->{must_not} }, { # the { starts a new hash ref 
    "regexp" => { 
     "designation" => "[Ff]+[Oo]+", # we like trailing commas in Perl 
    }, 
}; 

あなたは非常に新しいPerlの(5.24)を持っている場合は、あなたも読んで少しはきれいで、ここで接尾DEREF構文を、使用することができます。

push $result->{query}->{bool}->{must_not}->@, { ... }; 
+1

あなたの助けをありがとう、私は今私が欲しいものを正確に行うことができます、そして、あなたは私が間違っていたことの非常にきちんとした説明を提供しました! – SmashingQuasar

1

ハッシュリファレンスdecode_jsonリターンで直接作業することができます。例えば、

  1. はハッシュリファレンス

    push(@{$mustNots}, {"regexp" => {"designation" => "[Ff]+[Oo]+"}}); 
    
  2. を押すことで、この配列にフィルタを追加するには、must_not配列

    my $mustNots = $result->{query}->{bool}->{must_not}; 
    
  3. への参照を取得し、あなたは今、3番目のエントリを持っていますmust_notprint encode_json($result);

+0

あなたのお手伝いをしていただきありがとうございます。あなたの答えを@simbabqueの回答と組み合わせて、私は今問題点を理解しました。 – SmashingQuasar

関連する問題