├── .gitignore ├── example ├── .gitignore ├── populate_collection.sh ├── examples.sh ├── get_user_ids_for_page.sh ├── list-pages.sh ├── run-multiple-queries.sh ├── create_index.sh ├── word_query.sh ├── example_query_jesus.sh └── example_query_jesus_expain.sh ├── src └── main │ ├── resources │ └── plugin-descriptor.properties │ ├── assemblies │ └── plugin.xml │ └── java │ └── stefansavev │ └── esplugins │ ├── OverlapSimilarityPlugin.java │ ├── OverlapSimilarityProvider.java │ └── OverlapSimilarity.java ├── deploy-script.sh ├── README.md └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | .git/ 2 | .idea/ 3 | *.iml 4 | *.ipr 5 | 6 | target 7 | *~ 8 | 9 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | query1.tmp 3 | query1.result 4 | query2.tmp 5 | query2.result 6 | run-multiple-queries.tmp 7 | multiple-query.results 8 | -------------------------------------------------------------------------------- /example/populate_collection.sh: -------------------------------------------------------------------------------- 1 | echo "uploading data.txt to elasticsearch" 2 | curl -s -XPOST localhost:9200/_bulk?pretty --data-binary "@data.txt"; echo 3 | 4 | -------------------------------------------------------------------------------- /example/examples.sh: -------------------------------------------------------------------------------- 1 | echo "query: page_god" 2 | time ./word_query.sh "page_god" 3 | 4 | echo "query: page_encryption" 5 | time ./word_query.sh "page_encryption" 6 | -------------------------------------------------------------------------------- /example/get_user_ids_for_page.sh: -------------------------------------------------------------------------------- 1 | curl -XGET 'localhost:9200/page_clicks/pages/_search' -d' 2 | { 3 | "query" : { 4 | "match" : { 5 | "page_id" : "page_another" 6 | } 7 | } 8 | } 9 | ' 10 | -------------------------------------------------------------------------------- /src/main/resources/plugin-descriptor.properties: -------------------------------------------------------------------------------- 1 | description=Overlap Similarity Plugin 2 | version=0.0.1-SNAPSHOT 3 | jvm=true 4 | name=overlap-similarity-plugin 5 | elasticsearch.version=2.1.1 6 | java.version=1.8 7 | classname=stefansavev.esplugins.OverlapSimilarityPlugin 8 | -------------------------------------------------------------------------------- /example/list-pages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eu 4 | export SIZE=10 5 | if [ "$#" -eq 1 ]; then 6 | export SIZE=$1 7 | fi 8 | 9 | echo $SIZE 10 | 11 | curl -XGET 'localhost:9200/page_clicks/pages/_search?pretty' -d '{ 12 | "_source": [ "page_id" ], 13 | size: '"$SIZE"', 14 | "query": { 15 | "match_all": {} 16 | } 17 | }' 18 | -------------------------------------------------------------------------------- /example/run-multiple-queries.sh: -------------------------------------------------------------------------------- 1 | ./list-pages.sh 1000 | grep page_id | sed s/\"_source\":\{\"page_id\"\:\"// | sed s/\"\}// | awk '{print "echo ", $1, " && time ./word_query.sh ", $1}' > run-multiple-queries.tmp 2 | 3 | chmod +x run-multiple-queries.tmp 4 | 5 | #./run-multiple-queries.tmp 6 | 7 | #output only the query results to a file 8 | echo "outputing results to multiple-query.results" 9 | ./run-multiple-queries.tmp 2>&1 1 > multiple-query.results | grep real 10 | 11 | -------------------------------------------------------------------------------- /src/main/assemblies/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | plugin 4 | 5 | zip 6 | 7 | false 8 | 9 | 10 | / 11 | true 12 | true 13 | 14 | org.elasticsearch:elasticsearch 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/java/stefansavev/esplugins/OverlapSimilarityPlugin.java: -------------------------------------------------------------------------------- 1 | package stefansavev.esplugins; 2 | 3 | import org.elasticsearch.index.similarity.SimilarityModule; 4 | import org.elasticsearch.plugins.Plugin; 5 | 6 | public class OverlapSimilarityPlugin extends Plugin { 7 | 8 | @Override 9 | public String name() { 10 | return "overlap-similarity-plugin"; 11 | } 12 | 13 | @Override 14 | public String description() { 15 | return "Overlap Similarity Plugin"; 16 | } 17 | 18 | public void onModule(final SimilarityModule module) { 19 | module.addSimilarity("overlapsimilarity", OverlapSimilarityProvider.class); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/stefansavev/esplugins/OverlapSimilarityProvider.java: -------------------------------------------------------------------------------- 1 | package stefansavev.esplugins; 2 | 3 | import org.apache.lucene.search.similarities.Similarity; 4 | import org.elasticsearch.common.inject.Inject; 5 | import org.elasticsearch.common.inject.assistedinject.Assisted; 6 | import org.elasticsearch.common.settings.Settings; 7 | import org.elasticsearch.index.similarity.*; 8 | 9 | public class OverlapSimilarityProvider extends AbstractSimilarityProvider { 10 | 11 | private OverlapSimilarity similarity; 12 | 13 | @Inject 14 | public OverlapSimilarityProvider(@Assisted String name, @Assisted Settings settings) { 15 | super(name); 16 | this.similarity = new OverlapSimilarity(); 17 | } 18 | 19 | @Override 20 | public Similarity get() { 21 | return similarity; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /example/create_index.sh: -------------------------------------------------------------------------------- 1 | #if the index exists you may want to delete it first when testing 2 | 3 | curl -XDELETE 'http://localhost:9200/page_clicks/' 4 | 5 | curl -XPUT 'localhost:9200/page_clicks' -d ' 6 | { 7 | "settings" : { 8 | "index" : { 9 | "number_of_shards" : 1, 10 | "number_of_replicas" : 1, 11 | "store": "memory" 12 | }, 13 | 14 | "similarity" : { 15 | "custom_similarity" : { 16 | "type" : "overlapsimilarity" 17 | } 18 | } 19 | } 20 | } 21 | ' 22 | 23 | curl -XGET 'http://localhost:9200/page_clicks/_settings?pretty' 24 | 25 | curl -XPUT 'localhost:9200/page_clicks/_mapping/pages' -d ' 26 | { 27 | "properties": { 28 | "page_id": { 29 | "type": "string", 30 | "index": "not_analyzed" 31 | }, 32 | "user_ids": { 33 | "type": "string", 34 | "analyzer": "standard", 35 | "index_options": "docs", 36 | "similarity": "custom_similarity" 37 | } 38 | } 39 | } 40 | ' 41 | 42 | 43 | 44 | curl -XGET 'http://localhost:9200/page_clicks/_mappings/pages?pretty' 45 | 46 | -------------------------------------------------------------------------------- /example/word_query.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eu 4 | 5 | if [ "$#" -ne 1 ]; then 6 | echo "Illegal number of parameters" 7 | echo "Example: ./word_query.sh page_encryption" 8 | exit 1 9 | fi 10 | 11 | WORD=$1 12 | 13 | cat < query1.tmp 14 | curl -XGET 'localhost:9200/page_clicks/pages/_search' -d' 15 | { 16 | "query" : { 17 | "match" : { 18 | "page_id" : "$WORD" 19 | } 20 | } 21 | } 22 | ' 23 | EOF 24 | 25 | chmod +x ./query1.tmp 26 | ./query1.tmp > query1.result 27 | 28 | cat < query2.tmp 29 | curl -XGET 'localhost:9200/page_clicks/pages/_search?pretty' -d' 30 | { 31 | "_source": [ "page_id" ], 32 | size: 20, 33 | "query": { 34 | "match" : { 35 | EOF 36 | 37 | 38 | 39 | awk 'BEGIN { FS = "\"" } ; { 40 | for(i=1; i<=NF; i++) { 41 | tmp=match($i, /user_ids/) 42 | if(tmp) { 43 | print ("\"user_ids\" : \"", $(i + 2),"\"") 44 | break 45 | } 46 | } 47 | }' query1.result >> query2.tmp 48 | 49 | #echo $USER_IDS 50 | 51 | cat <> query2.tmp 52 | } 53 | }, 54 | "aggs": {} 55 | } 56 | ' 57 | EOF 58 | 59 | chmod +x ./query2.tmp 60 | ./query2.tmp > query2.result 61 | 62 | cat query2.result | grep "_source" | sed s/\"_source\"\:// 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /deploy-script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e #fail on error 4 | set -u #fail on undefined 5 | 6 | echoerr() { echo "Error: $@" 1>&2; } #write an error to stderr 7 | 8 | #set the variable to your elasticsearch installation 9 | 10 | ES_DIR=/home/stefan2/elastic-code/download/elasticsearch-2.1.1/ 11 | 12 | if [ ! -d "$ES_DIR" ]; then 13 | echoerr "ElasticSearch directory $ES_DIR does not exist" 14 | exit 1 15 | fi 16 | 17 | PLUGIN_CMD=$ES_DIR/bin/plugin 18 | 19 | CURRENT_SCRIPT=$(readlink -f $0) #get the path of the current script 20 | CURRENT_DIR=$(dirname "${CURRENT_SCRIPT}") #get the directory of the current script 21 | 22 | JAR_FILE="overlap-similarity-plugin-0.0.1-SNAPSHOT.jar" #name of the jar file 23 | PLUGIN_NAME="overlap-similarity-plugin" 24 | 25 | FULL_JAR_FILE_PATH=$CURRENT_DIR/target/$JAR_FILE 26 | 27 | if [ ! -f "$FULL_JAR_FILE_PATH" ]; then 28 | echoerr "Plugin jar file does not exist in $FULL_JAR_FILE_PATH" 29 | exit 1 30 | fi 31 | 32 | ls $FULL_JAR_FILE_PATH 33 | 34 | echo "Checking if a previous installation of the plugin exists" 35 | LIST_RESULT=$(${PLUGIN_CMD} list | grep "${PLUGIN_NAME}") 36 | echo $LIST_RESULT 37 | 38 | if [[ $LIST_RESULT == *"${PLUGIN_NAME}"* ]] 39 | then 40 | echo "Plugin is already installed. Need to remove it first!"; 41 | ${PLUGIN_CMD} remove ${PLUGIN_NAME} 42 | fi 43 | 44 | 45 | echo "Installing plugin" 46 | ${PLUGIN_CMD} install file:${FULL_JAR_FILE_PATH} 47 | 48 | echo "Done." 49 | echo "Asking for a list of installed plugins. You should see our plugin: ${PLUGIN_NAME}" 50 | ${PLUGIN_CMD} list 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # elasticsearch-custom-similarity-example 2 | 3 | Blog post describing the stages to create the custom similarity plugin 4 | 5 | Steps to run the code: 6 | 7 | 1. mvn clean install 8 | 9 | 2. Edit deploy_script.sh 10 |
    
11 |    Set the location of elasticsearch
12 |    ES_DIR=/home/stefan2/elastic-code/download/elasticsearch-2.1.1/
13 |    
14 | 15 | 3. Run deploy_script.sh 16 | 17 | 4. edit the script that starts elasticsearch 18 |
19 |    Edit elasticsearch-2.1.1/bin/elasticsearch to include the plugin jars in the elasticsearch classpath
20 |    ES_CLASSPATH="$ES_CLASSPATH:${ES_HOME}/plugins/overlap-similarity-plugin/"
21 |    
22 | 23 | 5. Restart elasticsearch 24 | 25 | 6. Create the page_clicks index 26 |
   
27 |    cd example
28 |    ./create_index.sh
29 | 
30 | 31 | 7. Load the dataset into elasticsearch 32 |
   
33 |    cd example
34 |    ./populate_collection.sh
35 | 
36 | 37 | 8. Run the example queries 38 |
39 |    cd example
40 |    ./examples.sh
41 |   
42 | 43 | 9. Check the output of ./examples.sh 44 | 45 |
46 |       query: page_god
47 |       "_source":{"page_id":"page_god"}
48 |       "_source":{"page_id":"page_jesus"}
49 |       "_source":{"page_id":"page_christian"}
50 |       "_source":{"page_id":"page_believe"}
51 |       "_source":{"page_id":"page_him"}
52 |       "_source":{"page_id":"page_life"}
53 |       "_source":{"page_id":"page_bible"}
54 |       "_source":{"page_id":"page_christians"}
55 |       "_source":{"page_id":"page_our"}
56 |       "_source":{"page_id":"page_must"}
57 |       "_source":{"page_id":"page_his"}
58 |       "_source":{"page_id":"page_fact"}
59 |       "_source":{"page_id":"page_apr"}
60 |       "_source":{"page_id":"page_things"}
61 |       "_source":{"page_id":"page_true"}
62 |       "_source":{"page_id":"page_christ"}
63 |       "_source":{"page_id":"page_man"}
64 |       "_source":{"page_id":"page_say"}
65 |       "_source":{"page_id":"page_come"}
66 |       "_source":{"page_id":"page_being"}
67 |   
68 | 69 |
70 |   query: page_encryption
71 |       "_source":{"page_id":"page_encryption"}
72 |       "_source":{"page_id":"page_clipper"}
73 |       "_source":{"page_id":"page_chip"}
74 |       "_source":{"page_id":"page_key"}
75 |       "_source":{"page_id":"page_keys"}
76 |       "_source":{"page_id":"page_secure"}
77 |       "_source":{"page_id":"page_algorithm"}
78 |       "_source":{"page_id":"page_escrow"}
79 |       "_source":{"page_id":"page_security"}
80 |       "_source":{"page_id":"page_secret"}
81 |       "_source":{"page_id":"page_crypto"}
82 |       "_source":{"page_id":"page_government"}
83 |       "_source":{"page_id":"page_house"}
84 |       "_source":{"page_id":"page_wiretap"}
85 |       "_source":{"page_id":"page_announcement"}
86 |       "_source":{"page_id":"page_privacy"}
87 |       "_source":{"page_id":"page_nsa"}
88 |       "_source":{"page_id":"page_white"}
89 |       "_source":{"page_id":"page_encrypted"}
90 |       "_source":{"page_id":"page_pgp"}
91 |   
92 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | stefansavev.esplugins 5 | overlap-similarity-plugin 6 | 0.0.1-SNAPSHOT 7 | jar 8 | overlap-similarity-plugin 9 | A plugin demonstrating how to define a new similarity for ElasticSearch 10 | 2015 11 | 12 | 13 | The Apache Software License, Version 2.0 14 | http://www.apache.org/licenses/LICENSE-2.0.txt 15 | repo 16 | 17 | 18 | 19 | 20 | 21 | 2.1.1 22 | 23 | 24 | 25 | 26 | src/main/resources 27 | true 28 | 29 | **/*.properties 30 | 31 | 32 | 33 | 34 | 35 | org.apache.maven.plugins 36 | maven-compiler-plugin 37 | 2.3.2 38 | 39 | 1.8 40 | 1.8 41 | 42 | 43 | 44 | org.apache.maven.plugins 45 | maven-surefire-plugin 46 | 2.11 47 | 48 | 49 | **/*Test.java 50 | 51 | 52 | 53 | 54 | org.apache.maven.plugins 55 | maven-source-plugin 56 | 2.1.2 57 | 58 | 59 | attach-sources 60 | 61 | jar 62 | 63 | 64 | 65 | 66 | 67 | org.apache.maven.plugins 68 | maven-javadoc-plugin 69 | 70 | -Xdoclint:none 71 | 72 | 73 | 74 | maven-assembly-plugin 75 | 76 | false 77 | ${project.build.directory}/releases/ 78 | 79 | ${basedir}/src/main/assemblies/plugin.xml 80 | 81 | 82 | 83 | 84 | package 85 | 86 | single 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | org.elasticsearch 96 | elasticsearch 97 | ${elasticsearch.version} 98 | provided 99 | 100 | 101 | junit 102 | junit 103 | 4.11 104 | test 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /src/main/java/stefansavev/esplugins/OverlapSimilarity.java: -------------------------------------------------------------------------------- 1 | package stefansavev.esplugins; 2 | 3 | import org.apache.lucene.index.FieldInvertState; 4 | import org.apache.lucene.index.LeafReaderContext; 5 | import org.apache.lucene.index.NumericDocValues; 6 | import org.apache.lucene.search.CollectionStatistics; 7 | import org.apache.lucene.search.Explanation; 8 | import org.apache.lucene.search.TermStatistics; 9 | import org.apache.lucene.search.similarities.DefaultSimilarity; 10 | import org.apache.lucene.search.similarities.Similarity; 11 | import org.apache.lucene.util.BytesRef; 12 | 13 | import java.io.IOException; 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | 18 | @SuppressWarnings("serial") 19 | public class OverlapSimilarity extends Similarity { 20 | 21 | public float queryNorm(float valueForNormalization) { 22 | return 1.0F; 23 | } 24 | 25 | //called at indexing time to compute the norm of a document 26 | public final long computeNorm(FieldInvertState state) { 27 | final int numTerms = state.getLength(); 28 | return (long)numTerms; 29 | } 30 | 31 | private static class OverlapStats extends Similarity.SimWeight { 32 | private final String field; 33 | private float queryWeight; 34 | 35 | public OverlapStats(String field, float queryWeight) { 36 | this.field = field; 37 | this.queryWeight = queryWeight; 38 | } 39 | 40 | @Override 41 | public float getValueForNormalization() { 42 | return 1.0f; 43 | } 44 | 45 | @Override 46 | public void normalize(float queryNorm, float topLevelBoost) { 47 | float w = 1.0f/queryNorm; 48 | queryWeight = w*w; 49 | } 50 | } 51 | 52 | @Override 53 | public final SimWeight computeWeight(float queryBoost, CollectionStatistics collectionStats, TermStatistics... termStats) { 54 | float numTerms = (float)termStats.length; 55 | return new OverlapStats(collectionStats.field(), numTerms); 56 | } 57 | 58 | @Override 59 | public final SimScorer simScorer(SimWeight stats, LeafReaderContext context) throws IOException { 60 | OverlapStats overlapStats = (OverlapStats) stats; 61 | return new OverlapScorer(overlapStats, context.reader().getNormValues(overlapStats.field)); 62 | } 63 | 64 | private final class OverlapScorer extends SimScorer { 65 | private final OverlapStats stats; 66 | private final NumericDocValues norms; 67 | 68 | OverlapScorer(OverlapStats stats, NumericDocValues norms) throws IOException { 69 | this.stats = stats; 70 | this.norms = norms; 71 | } 72 | 73 | @Override 74 | public float score(int doc, float freq) { 75 | final float raw = 1.0f; //ignore freq 76 | long docWeight = norms.get(doc); 77 | float queryWeight = stats.queryWeight; 78 | float norm = Math.max((float)docWeight, queryWeight); 79 | return norms == null ? raw : raw / norm; 80 | } 81 | 82 | //we don't use pharses 83 | @Override 84 | public float computeSlopFactor(int distance) { 85 | return 1.0f; 86 | } 87 | 88 | //we don't use payload 89 | @Override 90 | public float computePayloadFactor(int doc, int start, int end, BytesRef payload) { 91 | return 1.0f; 92 | } 93 | 94 | @Override 95 | public Explanation explain(int doc, Explanation freq) { 96 | Explanation fieldNormExpl = Explanation.match( 97 | norms != null ? (norms.get(doc)) : 1.0f, 98 | "fieldNorm(doc=" + doc + ")"); 99 | float queryWeight = stats.queryWeight; 100 | Explanation docWeightExpl = Explanation.match(queryWeight, "queryWeight"); 101 | return Explanation.match(1.0f, "singlematch", fieldNormExpl, docWeightExpl); 102 | } 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /example/example_query_jesus.sh: -------------------------------------------------------------------------------- 1 | curl -XGET 'localhost:9200/page_clicks/pages/_search?pretty' -d' 2 | { 3 | "_source": [ "page_id" ], 4 | size: 20, 5 | "query": { 6 | "match" : { 7 | "user_ids": "user_7462 user_3821 user_8162 user_3844 user_8338 user_7917 user_8098 user_9006 user_1553 user_1120 user_8732 user_6619 user_8142 user_10355 user_3538 user_3799 user_7418 user_3790 user_7560 user_7452 user_7738 user_7538 user_7416 user_7638 user_3660 user_7817 user_3619 user_3632 user_3740 user_3843 user_1304 user_3414 user_8365 user_8322 user_3444 user_7567 user_2944 user_8076 user_3600 user_9295 user_10947 user_8165 user_7440 user_7574 user_8307 user_7396 user_10516 user_7913 user_1944 user_7838 user_7953 user_3835 user_7984 user_9584 user_3758 user_9065 user_10653 user_7794 user_2020 user_8289 user_7850 user_9736 user_2147 user_3574 user_8130 user_7986 user_8033 user_7614 user_7654 user_3686 user_7973 user_7423 user_3774 user_7431 user_8110 user_3816 user_7395 user_3503 user_7565 user_3625 user_7916 user_8224 user_3390 user_7421 user_3552 user_1744 user_7781 user_7592 user_7650 user_7648 user_7665 user_10577 user_7429 user_9107 user_8192 user_3380 user_9069 user_3782 user_7669 user_7580 user_11218 user_7559 user_7435 user_7508 user_7607 user_7764 user_7655 user_3628 user_7513 user_7671 user_7826 user_11102 user_3839 user_7910 user_9233 user_3580 user_3471 user_9170 user_8043 user_7055 user_7485 user_3757 user_7497 user_8102 user_8591 user_8276 user_7477 user_2983 user_8231 user_7705 user_8252 user_7721 user_7784 user_7922 user_9881 user_7900 user_3841 user_9483 user_3434 user_8348 user_5651 user_7723 user_8234 user_3474 user_7258 user_3731 user_3791 user_7754 user_8088 user_3670 user_6367 user_8369 user_8012 user_7502 user_3465 user_7598 user_7397 user_3453 user_7444 user_7975 user_7566 user_7432 user_3399 user_7450 user_3497 user_3417 user_3371 user_2115 user_3102 user_3562 user_8262 user_7523 user_7971 user_3440 user_8950 user_7571 user_1151 user_7948 user_8345 user_7793 user_7561 user_7546 user_7956 user_8039 user_8349 user_3166 user_7521 user_9995 user_7874 user_7503 user_7743 user_9445 user_8097 user_2958 user_7415 user_3526 user_4574 user_7880 user_7682 user_3442 user_7907 user_3473 user_7109 user_8101 user_3743 user_3652 user_4408 user_9167 user_7464 user_7630 user_3653 user_7414 user_1787 user_10629 user_7985 user_7454 user_7659 user_7770 user_5423 user_3461 user_8166 user_7941 user_8288 user_3827 user_7719 user_3709 user_7640 user_3796 user_3820 user_7428 user_3507 user_8347 user_7691 user_3591 user_7899 user_7915 user_7411 user_3536 user_3055 user_7512 user_8062 user_8150 user_11006 user_7932 user_7402 user_7600 user_3840 user_9453 user_8317 user_3238 user_1896 user_3813 user_8203 user_8180 user_7652 user_7553 user_3741 user_7113 user_3262 user_7635 user_8161 user_2888 user_3768 user_7407 user_7426 user_7726 user_7620 user_7563 user_8323 user_7679 user_8125 user_3391 user_7539 user_2287 user_7517 user_3769 user_7746 user_3488 user_7777 user_2517 user_1791 user_7390 user_8201 user_3529 user_7789 user_1979 user_3719 user_3499 user_7882 user_8122 user_7610 user_167 user_7995 user_7994 user_7446 user_7417 user_8120 user_7960 user_8236 user_7456 user_3548 user_1085 user_9320 user_7999 user_3472 user_7532 user_7536 user_3824 user_7677 user_8277 user_540 user_3405 user_1778 user_8094 user_7398 user_8208 user_7437 user_3690 user_7976 user_8530 user_7787 user_7622 user_8351 user_8210 user_7617 user_5258 user_8285 user_7596 user_7664 user_8324 user_8013 user_3773 user_9848 user_2438 user_7405 user_7774 user_1804 user_10705 user_3404 user_7816 user_7514 user_8085 user_7637 user_8299 user_8065 user_7690 user_7791 user_7668 user_3593 user_7534 user_7458 user_8336 user_8069 user_7959 user_3512 user_2712 user_10421 user_8333 user_7982 user_3487 user_2876 user_3729 user_7473 user_3374 user_8001 user_9070 user_7540 user_3482 user_9099 user_7632 user_3722 user_2067 user_3836 user_7909 user_3671 user_3727 user_931 user_9296 user_9008 user_6833 user_7706 user_8167 user_2060 user_7643 user_7645 user_9746 user_8148 user_7718 user_10714 user_7731 user_7646 user_7509 user_7990 user_8362 user_3541 user_8313 user_8011 user_7651 user_8024 user_7710 user_7734 user_8194 user_7729 user_7492 user_8111 user_7735 user_7554 user_7892 user_3597 user_8005 user_8216 user_7894 user_7861 user_3721 user_3822 user_9509 user_9411 user_3606 user_7891 user_7631 user_4977 user_7410 user_7812 user_7864 user_7483 user_8269 user_7854 user_7634 user_2563 user_8146 user_7801 user_10237 user_7495 user_3117 user_7624 user_7888 user_8185 user_7751 user_8079 user_3394 user_8649 user_7628 user_7979 user_7541 user_8361 user_7568 user_7811 user_3501 user_2449 user_7775 user_7835 user_3641 user_3137 user_7866 user_3624 user_8213 user_3705 user_8051 user_7724 user_10731 user_8335 user_7851 user_7845 user_7562 user_7761 user_7666 user_7714 user_5250 user_7504 user_8791 user_8095 user_8305 user_7752 user_7972 user_930 user_3369 user_2200 user_3368 user_3678 user_7736 user_8049 user_7439 user_7527 user_3389 user_3451 user_8073 user_7578 user_7927 user_7849 user_3544 user_7551 user_8222 user_7779 user_2134 user_7542 user_8106 user_7695 user_8214 user_9019 user_2164 user_8009 user_8020 user_7577 user_7466 user_9254 user_7447 user_7765 user_3675 user_7821 user_7870 user_6849 user_7676 user_7636 user_7399 user_3634 user_7448 user_7890 user_7749 user_8191 user_7564 user_11270 user_3508 user_8015 user_3518 user_7844 user_882 user_3644 user_7479 user_7475 user_7605 user_3047 user_9547 user_3425 user_6978 user_7434 user_7701 user_105 user_8242 user_7808 user_7740 user_3086 user_7613 user_7511 user_3710 user_7792 user_7422 user_7489 user_8430 user_7529 user_3590 user_8071 user_3691 user_2846 user_7604 user_3563 user_3438 user_7896 user_3736 user_7708 user_8138 user_7766 user_7886 user_3754 user_7720 user_7670 user_3626 user_7809 user_7818 user_8226 user_8259 user_7833 user_7117 user_7550 user_3433 user_5762 user_8225 user_7803 user_8113 user_7658 user_3814 user_3706 user_3110 user_4619 user_7461 user_7847 user_3505 user_8205 user_3735 user_3838 user_8054 user_10679 user_3571 user_3278 user_9186 user_6845 user_7616 user_7680 user_7980 user_3831 user_7842 user_7496 user_9281 user_7516 user_8193 user_7556 user_3491 user_8297 user_3199 user_3555 user_8057 user_3421 user_7965 user_7442 user_7841 user_3778 user_8086 user_2088 user_7810 user_3702 user_3672 user_8047 user_6643 user_7737 user_7687 user_8233 user_7958 user_2312 user_3608 user_7581 user_8195 user_7400 user_10646 user_8025 user_3062 user_7589 user_7957 user_993 user_2873 user_7090 user_8199 user_3484 user_7776 user_3364 user_7537 user_7977 user_7672 user_5972 user_3659 user_7533 user_3510 user_2236 user_8084 user_7920 user_3601 user_1342 user_7459 user_7767 user_1925 user_9598 user_7819 user_7991 user_7424 user_3533 user_3450 user_8169 user_3750 user_7713 user_3578 user_8243 user_7966 user_2232 user_7425 user_7678 user_7591 user_7785 user_8133 user_7943 user_7732 user_7800 user_3829 user_8254 user_7500 user_3780 user_7449 user_3635 user_3745 user_3377 user_3819 user_3517 user_8281 user_7700 user_3765 user_8308 user_7938 user_3490 user_9245 user_7802 user_7790 user_7739 user_7409 user_7814 user_10567 user_7606 user_2117 user_3090 user_3845 user_7983 user_595 user_8278 user_8325 user_8121 user_7945 user_8332 user_3398 user_2847 user_7686 user_7662 user_7914 user_3430 user_7878 user_7921 user_7717 user_10942 user_7758 user_7472 user_7846 user_3664 user_7413 user_6415 user_8099 user_10351 user_8157 user_3766 user_3650 user_7438 user_7430 user_3485 user_8263 user_1938 user_7490 user_3629 user_7684 user_8087 user_8052 user_8260 user_3498 user_3220 user_3401 user_3693 user_10666 user_7877 user_7840 user_9579 user_7923 user_3534 user_7569 user_8197 user_3811 user_3313 user_7656 user_7744 user_7685 user_7641 user_3604 user_7507 user_3493 user_3688 user_7798 user_10541 user_3565 user_7898 user_7887 user_10683 user_7753 user_7457 user_3680 user_7673 user_7825 user_3818 user_4374 user_10336 user_3639 user_3714 user_7603 user_3475 user_7535 user_7515 user_7828 user_8221 user_3455 user_8292 user_8829 user_7843 user_7727 user_3623 user_3406 user_7935 user_8238 user_8337 user_8008 user_3800 user_8355 user_7528 user_7905 user_7548 user_8036 user_8164" 8 | 9 | } 10 | }, 11 | "aggs": {} 12 | } 13 | ' 14 | -------------------------------------------------------------------------------- /example/example_query_jesus_expain.sh: -------------------------------------------------------------------------------- 1 | curl -XGET 'localhost:9200/page_clicks/pages/_search?pretty&explain' -d' 2 | { 3 | "_source": [ "page_id" ], 4 | size: 20, 5 | "query": { 6 | "match" : { 7 | "user_ids": "user_7462 user_3821 user_8162 user_3844 user_8338 user_7917 user_8098 user_9006 user_1553 user_1120 user_8732 user_6619 user_8142 user_10355 user_3538 user_3799 user_7418 user_3790 user_7560 user_7452 user_7738 user_7538 user_7416 user_7638 user_3660 user_7817 user_3619 user_3632 user_3740 user_3843 user_1304 user_3414 user_8365 user_8322 user_3444 user_7567 user_2944 user_8076 user_3600 user_9295 user_10947 user_8165 user_7440 user_7574 user_8307 user_7396 user_10516 user_7913 user_1944 user_7838 user_7953 user_3835 user_7984 user_9584 user_3758 user_9065 user_10653 user_7794 user_2020 user_8289 user_7850 user_9736 user_2147 user_3574 user_8130 user_7986 user_8033 user_7614 user_7654 user_3686 user_7973 user_7423 user_3774 user_7431 user_8110 user_3816 user_7395 user_3503 user_7565 user_3625 user_7916 user_8224 user_3390 user_7421 user_3552 user_1744 user_7781 user_7592 user_7650 user_7648 user_7665 user_10577 user_7429 user_9107 user_8192 user_3380 user_9069 user_3782 user_7669 user_7580 user_11218 user_7559 user_7435 user_7508 user_7607 user_7764 user_7655 user_3628 user_7513 user_7671 user_7826 user_11102 user_3839 user_7910 user_9233 user_3580 user_3471 user_9170 user_8043 user_7055 user_7485 user_3757 user_7497 user_8102 user_8591 user_8276 user_7477 user_2983 user_8231 user_7705 user_8252 user_7721 user_7784 user_7922 user_9881 user_7900 user_3841 user_9483 user_3434 user_8348 user_5651 user_7723 user_8234 user_3474 user_7258 user_3731 user_3791 user_7754 user_8088 user_3670 user_6367 user_8369 user_8012 user_7502 user_3465 user_7598 user_7397 user_3453 user_7444 user_7975 user_7566 user_7432 user_3399 user_7450 user_3497 user_3417 user_3371 user_2115 user_3102 user_3562 user_8262 user_7523 user_7971 user_3440 user_8950 user_7571 user_1151 user_7948 user_8345 user_7793 user_7561 user_7546 user_7956 user_8039 user_8349 user_3166 user_7521 user_9995 user_7874 user_7503 user_7743 user_9445 user_8097 user_2958 user_7415 user_3526 user_4574 user_7880 user_7682 user_3442 user_7907 user_3473 user_7109 user_8101 user_3743 user_3652 user_4408 user_9167 user_7464 user_7630 user_3653 user_7414 user_1787 user_10629 user_7985 user_7454 user_7659 user_7770 user_5423 user_3461 user_8166 user_7941 user_8288 user_3827 user_7719 user_3709 user_7640 user_3796 user_3820 user_7428 user_3507 user_8347 user_7691 user_3591 user_7899 user_7915 user_7411 user_3536 user_3055 user_7512 user_8062 user_8150 user_11006 user_7932 user_7402 user_7600 user_3840 user_9453 user_8317 user_3238 user_1896 user_3813 user_8203 user_8180 user_7652 user_7553 user_3741 user_7113 user_3262 user_7635 user_8161 user_2888 user_3768 user_7407 user_7426 user_7726 user_7620 user_7563 user_8323 user_7679 user_8125 user_3391 user_7539 user_2287 user_7517 user_3769 user_7746 user_3488 user_7777 user_2517 user_1791 user_7390 user_8201 user_3529 user_7789 user_1979 user_3719 user_3499 user_7882 user_8122 user_7610 user_167 user_7995 user_7994 user_7446 user_7417 user_8120 user_7960 user_8236 user_7456 user_3548 user_1085 user_9320 user_7999 user_3472 user_7532 user_7536 user_3824 user_7677 user_8277 user_540 user_3405 user_1778 user_8094 user_7398 user_8208 user_7437 user_3690 user_7976 user_8530 user_7787 user_7622 user_8351 user_8210 user_7617 user_5258 user_8285 user_7596 user_7664 user_8324 user_8013 user_3773 user_9848 user_2438 user_7405 user_7774 user_1804 user_10705 user_3404 user_7816 user_7514 user_8085 user_7637 user_8299 user_8065 user_7690 user_7791 user_7668 user_3593 user_7534 user_7458 user_8336 user_8069 user_7959 user_3512 user_2712 user_10421 user_8333 user_7982 user_3487 user_2876 user_3729 user_7473 user_3374 user_8001 user_9070 user_7540 user_3482 user_9099 user_7632 user_3722 user_2067 user_3836 user_7909 user_3671 user_3727 user_931 user_9296 user_9008 user_6833 user_7706 user_8167 user_2060 user_7643 user_7645 user_9746 user_8148 user_7718 user_10714 user_7731 user_7646 user_7509 user_7990 user_8362 user_3541 user_8313 user_8011 user_7651 user_8024 user_7710 user_7734 user_8194 user_7729 user_7492 user_8111 user_7735 user_7554 user_7892 user_3597 user_8005 user_8216 user_7894 user_7861 user_3721 user_3822 user_9509 user_9411 user_3606 user_7891 user_7631 user_4977 user_7410 user_7812 user_7864 user_7483 user_8269 user_7854 user_7634 user_2563 user_8146 user_7801 user_10237 user_7495 user_3117 user_7624 user_7888 user_8185 user_7751 user_8079 user_3394 user_8649 user_7628 user_7979 user_7541 user_8361 user_7568 user_7811 user_3501 user_2449 user_7775 user_7835 user_3641 user_3137 user_7866 user_3624 user_8213 user_3705 user_8051 user_7724 user_10731 user_8335 user_7851 user_7845 user_7562 user_7761 user_7666 user_7714 user_5250 user_7504 user_8791 user_8095 user_8305 user_7752 user_7972 user_930 user_3369 user_2200 user_3368 user_3678 user_7736 user_8049 user_7439 user_7527 user_3389 user_3451 user_8073 user_7578 user_7927 user_7849 user_3544 user_7551 user_8222 user_7779 user_2134 user_7542 user_8106 user_7695 user_8214 user_9019 user_2164 user_8009 user_8020 user_7577 user_7466 user_9254 user_7447 user_7765 user_3675 user_7821 user_7870 user_6849 user_7676 user_7636 user_7399 user_3634 user_7448 user_7890 user_7749 user_8191 user_7564 user_11270 user_3508 user_8015 user_3518 user_7844 user_882 user_3644 user_7479 user_7475 user_7605 user_3047 user_9547 user_3425 user_6978 user_7434 user_7701 user_105 user_8242 user_7808 user_7740 user_3086 user_7613 user_7511 user_3710 user_7792 user_7422 user_7489 user_8430 user_7529 user_3590 user_8071 user_3691 user_2846 user_7604 user_3563 user_3438 user_7896 user_3736 user_7708 user_8138 user_7766 user_7886 user_3754 user_7720 user_7670 user_3626 user_7809 user_7818 user_8226 user_8259 user_7833 user_7117 user_7550 user_3433 user_5762 user_8225 user_7803 user_8113 user_7658 user_3814 user_3706 user_3110 user_4619 user_7461 user_7847 user_3505 user_8205 user_3735 user_3838 user_8054 user_10679 user_3571 user_3278 user_9186 user_6845 user_7616 user_7680 user_7980 user_3831 user_7842 user_7496 user_9281 user_7516 user_8193 user_7556 user_3491 user_8297 user_3199 user_3555 user_8057 user_3421 user_7965 user_7442 user_7841 user_3778 user_8086 user_2088 user_7810 user_3702 user_3672 user_8047 user_6643 user_7737 user_7687 user_8233 user_7958 user_2312 user_3608 user_7581 user_8195 user_7400 user_10646 user_8025 user_3062 user_7589 user_7957 user_993 user_2873 user_7090 user_8199 user_3484 user_7776 user_3364 user_7537 user_7977 user_7672 user_5972 user_3659 user_7533 user_3510 user_2236 user_8084 user_7920 user_3601 user_1342 user_7459 user_7767 user_1925 user_9598 user_7819 user_7991 user_7424 user_3533 user_3450 user_8169 user_3750 user_7713 user_3578 user_8243 user_7966 user_2232 user_7425 user_7678 user_7591 user_7785 user_8133 user_7943 user_7732 user_7800 user_3829 user_8254 user_7500 user_3780 user_7449 user_3635 user_3745 user_3377 user_3819 user_3517 user_8281 user_7700 user_3765 user_8308 user_7938 user_3490 user_9245 user_7802 user_7790 user_7739 user_7409 user_7814 user_10567 user_7606 user_2117 user_3090 user_3845 user_7983 user_595 user_8278 user_8325 user_8121 user_7945 user_8332 user_3398 user_2847 user_7686 user_7662 user_7914 user_3430 user_7878 user_7921 user_7717 user_10942 user_7758 user_7472 user_7846 user_3664 user_7413 user_6415 user_8099 user_10351 user_8157 user_3766 user_3650 user_7438 user_7430 user_3485 user_8263 user_1938 user_7490 user_3629 user_7684 user_8087 user_8052 user_8260 user_3498 user_3220 user_3401 user_3693 user_10666 user_7877 user_7840 user_9579 user_7923 user_3534 user_7569 user_8197 user_3811 user_3313 user_7656 user_7744 user_7685 user_7641 user_3604 user_7507 user_3493 user_3688 user_7798 user_10541 user_3565 user_7898 user_7887 user_10683 user_7753 user_7457 user_3680 user_7673 user_7825 user_3818 user_4374 user_10336 user_3639 user_3714 user_7603 user_3475 user_7535 user_7515 user_7828 user_8221 user_3455 user_8292 user_8829 user_7843 user_7727 user_3623 user_3406 user_7935 user_8238 user_8337 user_8008 user_3800 user_8355 user_7528 user_7905 user_7548 user_8036 user_8164" 8 | 9 | } 10 | }, 11 | "aggs": {} 12 | } 13 | ' 14 | --------------------------------------------------------------------------------