Python

Using Searchly with Python

Elasticsearch provides two types of clients for Python low-level and elasticsearch-dsl.

The library is compatible with all Elasticsearch versions since 0.90.x but you have to use a matching major version:

Set your requirements in your setup.py or requirements.txt is:

<span></span><span class="c1"># Elasticsearch 6.x</span>
elasticsearch><span class="o">=</span><span class="m">6</span>.0.0,<<span class="m">7</span>.0.0

<span class="c1"># Elasticsearch 5.x</span>
elasticsearch><span class="o">=</span><span class="m">5</span>.0.0,<<span class="m">6</span>.0.0

<span class="c1"># Elasticsearch 2.x</span>
elasticsearch><span class="o">=</span><span class="m">2</span>.0.0,<<span class="m">3</span>.0.0
			

Install via pip;

<span></span>$ pip install elasticsearch
			
<span></span><span class="kn">from</span> <span class="nn">elasticsearch</span> <span class="kn">import</span> <span class="n">Elasticsearch</span>

<span class="n">es</span> <span class="o">=</span> <span class="n">Elasticsearch</span><span class="p">([</span><span class="s1">'https://site:api-key@xyz.searchly.com:443'</span><span class="p">])</span>
			
<span></span><span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
<span class="kn">from</span> <span class="nn">elasticsearch</span> <span class="kn">import</span> <span class="n">Elasticsearch</span>
<span class="n">es</span> <span class="o">=</span> <span class="n">Elasticsearch</span><span class="p">([</span><span class="s1">'https://site:api-key@xyz.searchly.com:443'</span><span class="p">])</span>

<span class="n">doc</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s1">'author'</span><span class="p">:</span> <span class="s1">'kimchy'</span><span class="p">,</span>
    <span class="s1">'text'</span><span class="p">:</span> <span class="s1">'Elasticsearch: cool. bonsai cool.'</span>
<span class="p">}</span>

<span class="c1"># ignore 400 cause by IndexAlreadyExistsException when creating an index</span>
<span class="n">es</span><span class="o">.</span><span class="n">indices</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">index</span><span class="o">=</span><span class="s1">'test-index'</span><span class="p">,</span> <span class="n">ignore</span><span class="o">=</span><span class="mi">400</span><span class="p">)</span>

<span class="c1"># create tweet</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">es</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">index</span><span class="o">=</span><span class="s2">"test-index"</span><span class="p">,</span> <span class="n">doc_type</span><span class="o">=</span><span class="s1">'tweet'</span><span class="p">,</span> <span class="nb">id</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">body</span><span class="o">=</span><span class="n">doc</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">res</span><span class="p">[</span><span class="s1">'created'</span><span class="p">])</span>

<span class="c1"># get tweet</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">es</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">index</span><span class="o">=</span><span class="s2">"test-index"</span><span class="p">,</span> <span class="n">doc_type</span><span class="o">=</span><span class="s1">'tweet'</span><span class="p">,</span> <span class="nb">id</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">res</span><span class="p">[</span><span class="s1">'_source'</span><span class="p">])</span>

<span class="c1"># search tweet</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">es</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">index</span><span class="o">=</span><span class="s2">"test-index"</span><span class="p">,</span> <span class="n">body</span><span class="o">=</span><span class="p">{</span><span class="s2">"query"</span><span class="p">:</span> <span class="p">{</span><span class="s2">"match_all"</span><span class="p">:</span> <span class="p">{}}})</span>
<span class="k">print</span><span class="p">(</span><span class="s2">"Got </span><span class="si">%d</span><span class="s2"> Hits:"</span> <span class="o">%</span> <span class="n">res</span><span class="p">[</span><span class="s1">'hits'</span><span class="p">][</span><span class="s1">'total'</span><span class="p">])</span>
<span class="k">for</span> <span class="n">hit</span> <span class="ow">in</span> <span class="n">res</span><span class="p">[</span><span class="s1">'hits'</span><span class="p">][</span><span class="s1">'hits'</span><span class="p">]:</span>
    <span class="k">print</span><span class="p">(</span><span class="s2">"</span><span class="si">%(author)s</span><span class="s2">: </span><span class="si">%(text)s</span><span class="s2">"</span> <span class="o">%</span> <span class="n">hit</span><span class="p">[</span><span class="s2">"_source"</span><span class="p">])</span>
			

The library is compatible with all Elasticsearch versions since 1.x but you have to use a matching major version:

<span></span><span class="c1"># Elasticsearch 6.x</span>
<span class="n">elasticsearch</span><span class="o">-</span><span class="n">dsl</span><span class="o">>=</span><span class="mf">6.0</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span><span class="o"><</span><span class="mf">7.0</span><span class="o">.</span><span class="mi">0</span>

<span class="c1"># Elasticsearch 5.x</span>
<span class="n">elasticsearch</span><span class="o">-</span><span class="n">dsl</span><span class="o">>=</span><span class="mf">5.0</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span><span class="o"><</span><span class="mf">6.0</span><span class="o">.</span><span class="mi">0</span>

<span class="c1"># Elasticsearch 2.x</span>
<span class="n">elasticsearch</span><span class="o">-</span><span class="n">dsl</span><span class="o">>=</span><span class="mf">2.0</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span><span class="o"><</span><span class="mf">3.0</span><span class="o">.</span><span class="mi">0</span>

<span class="c1"># Elasticsearch 1.x</span>
<span class="n">elasticsearch</span><span class="o">-</span><span class="n">dsl</span><span class="o"><</span><span class="mf">2.0</span><span class="o">.</span><span class="mi">0</span>
			

You can either manually pass your connection instance to each request or set default connection for all requests.

<span></span><span class="n">s</span> <span class="o">=</span> <span class="n">Search</span><span class="p">(</span><span class="n">using</span><span class="o">=</span><span class="n">Elasticsearch</span><span class="p">(</span><span class="s1">'https://site:api-key@xyz.searchly.com:443'</span><span class="p">))</span>
			

To define a default connection that will be used globally, use the connections module and the create_connection method:

<span></span><span class="kn">from</span> <span class="nn">elasticsearch_dsl</span> <span class="kn">import</span> <span class="n">connections</span>

<span class="n">connections</span><span class="o">.</span><span class="n">create_connection</span><span class="p">(</span><span class="n">hosts</span><span class="o">=</span><span class="p">[</span><span class="s1">'https://site:api-key@xyz.searchly.com:443'</span><span class="p">],</span> <span class="n">timeout</span><span class="o">=</span><span class="mi">20</span><span class="p">)</span>
			

You can create model-like wrapper for your documents via using DocType class. It can provide mapping and settings for Elasticsearch.

<span></span><span class="kn">from</span> <span class="nn">elasticsearch_dsl</span> <span class="kn">import</span> <span class="n">DocType</span><span class="p">,</span> <span class="n">Date</span><span class="p">,</span> <span class="n">Nested</span><span class="p">,</span> <span class="n">Boolean</span><span class="p">,</span> \
    <span class="n">analyzer</span><span class="p">,</span> <span class="n">InnerDoc</span><span class="p">,</span> <span class="n">Completion</span><span class="p">,</span> <span class="n">Keyword</span><span class="p">,</span> <span class="n">Text</span>

<span class="n">html_strip</span> <span class="o">=</span> <span class="n">analyzer</span><span class="p">(</span><span class="s1">'html_strip'</span><span class="p">,</span>
    <span class="n">tokenizer</span><span class="o">=</span><span class="s2">"standard"</span><span class="p">,</span>
    <span class="nb">filter</span><span class="o">=</span><span class="p">[</span><span class="s2">"standard"</span><span class="p">,</span> <span class="s2">"lowercase"</span><span class="p">,</span> <span class="s2">"stop"</span><span class="p">,</span> <span class="s2">"snowball"</span><span class="p">],</span>
<span class="p">)</span>

<span class="k">class</span> <span class="nc">Comment</span><span class="p">(</span><span class="n">InnerDoc</span><span class="p">):</span>
    <span class="n">author</span> <span class="o">=</span> <span class="n">Text</span><span class="p">(</span><span class="n">fields</span><span class="o">=</span><span class="p">{</span><span class="s1">'raw'</span><span class="p">:</span> <span class="n">Keyword</span><span class="p">()})</span>
    <span class="n">content</span> <span class="o">=</span> <span class="n">Text</span><span class="p">(</span><span class="n">analyzer</span><span class="o">=</span><span class="s1">'snowball'</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Post</span><span class="p">(</span><span class="n">DocType</span><span class="p">):</span>
    <span class="n">title</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>
    <span class="n">title_suggest</span> <span class="o">=</span> <span class="n">Completion</span><span class="p">()</span>
    <span class="n">published</span> <span class="o">=</span> <span class="n">Boolean</span><span class="p">()</span>
    <span class="n">category</span> <span class="o">=</span> <span class="n">Text</span><span class="p">(</span>
        <span class="n">analyzer</span><span class="o">=</span><span class="n">html_strip</span><span class="p">,</span>
        <span class="n">fields</span><span class="o">=</span><span class="p">{</span><span class="s1">'raw'</span><span class="p">:</span> <span class="n">Keyword</span><span class="p">()}</span>
    <span class="p">)</span>

    <span class="n">comments</span> <span class="o">=</span> <span class="n">Nested</span><span class="p">(</span><span class="n">Comment</span><span class="p">)</span>

    <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
        <span class="n">index</span> <span class="o">=</span> <span class="s1">'blog'</span>

    <span class="k">def</span> <span class="nf">add_comment</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">author</span><span class="p">,</span> <span class="n">content</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">comments</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
          <span class="n">Comment</span><span class="p">(</span><span class="n">author</span><span class="o">=</span><span class="n">author</span><span class="p">,</span> <span class="n">content</span><span class="o">=</span><span class="n">content</span><span class="p">))</span>

    <span class="k">def</span> <span class="nf">save</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span> <span class="n">kwargs</span><span class="p">):</span>
        <span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="o">**</span> <span class="n">kwargs</span><span class="p">)</span>
			

Also you can explicitly create index and provide settings at index;

<span></span><span class="kn">from</span> <span class="nn">elasticsearch_dsl</span> <span class="kn">import</span> <span class="n">Index</span><span class="p">,</span> <span class="n">DocType</span><span class="p">,</span> <span class="n">Text</span><span class="p">,</span> <span class="n">analyzer</span>

<span class="n">blogs</span> <span class="o">=</span> <span class="n">Index</span><span class="p">(</span><span class="s1">'blogs'</span><span class="p">)</span>

<span class="c1"># define aliases</span>
<span class="n">blogs</span><span class="o">.</span><span class="n">aliases</span><span class="p">(</span>
    <span class="n">old_blogs</span><span class="o">=</span><span class="p">{}</span>
<span class="p">)</span>

<span class="c1"># register a doc_type with the index</span>
<span class="n">blogs</span><span class="o">.</span><span class="n">doc_type</span><span class="p">(</span><span class="n">Post</span><span class="p">)</span>

<span class="c1"># can also be used as class decorator when defining the DocType</span>
<span class="nd">@blogs.doc_type</span>
<span class="k">class</span> <span class="nc">Post</span><span class="p">(</span><span class="n">DocType</span><span class="p">):</span>
    <span class="n">title</span> <span class="o">=</span> <span class="n">Text</span><span class="p">()</span>

<span class="c1"># You can attach custom analyzers to the index</span>

<span class="n">html_strip</span> <span class="o">=</span> <span class="n">analyzer</span><span class="p">(</span><span class="s1">'html_strip'</span><span class="p">,</span>
    <span class="n">tokenizer</span><span class="o">=</span><span class="s2">"standard"</span><span class="p">,</span>
    <span class="nb">filter</span><span class="o">=</span><span class="p">[</span><span class="s2">"standard"</span><span class="p">,</span> <span class="s2">"lowercase"</span><span class="p">,</span> <span class="s2">"stop"</span><span class="p">,</span> <span class="s2">"snowball"</span><span class="p">],</span>
<span class="p">)</span>

<span class="n">blogs</span><span class="o">.</span><span class="n">analyzer</span><span class="p">(</span><span class="n">html_strip</span><span class="p">)</span>

<span class="c1"># delete the index, ignore if it doesn't exist</span>
<span class="n">blogs</span><span class="o">.</span><span class="n">delete</span><span class="p">(</span><span class="n">ignore</span><span class="o">=</span><span class="mi">404</span><span class="p">)</span>

<span class="c1"># create the index in elasticsearch</span>
<span class="n">blogs</span><span class="o">.</span><span class="n">create</span><span class="p">()</span>
			

Create and save documents to Elasticsearch;

<span></span><span class="c1"># instantiate the document</span>
<span class="n">first</span> <span class="o">=</span> <span class="n">Post</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s1">'My First Blog Post, yay!'</span><span class="p">,</span> <span class="n">published</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="c1"># assign some field values, can be values or lists of values</span>
<span class="n">first</span><span class="o">.</span><span class="n">category</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'everything'</span><span class="p">,</span> <span class="s1">'nothing'</span><span class="p">]</span>
<span class="c1"># every document has an id in meta</span>
<span class="n">first</span><span class="o">.</span><span class="n">meta</span><span class="o">.</span><span class="n">id</span> <span class="o">=</span> <span class="mi">47</span>


<span class="c1"># save the document into the cluster</span>
<span class="n">first</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
			
<span></span><span class="c1"># by calling .search we get back a standard Search object</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">Post</span><span class="o">.</span><span class="n">search</span><span class="p">()</span>
<span class="c1"># the search is already limited to the index and doc_type of our document</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="s1">'term'</span><span class="p">,</span> <span class="n">published</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s1">'match'</span><span class="p">,</span> <span class="n">title</span><span class="o">=</span><span class="s1">'first'</span><span class="p">)</span>


<span class="n">results</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">execute</span><span class="p">()</span>

<span class="c1"># when you execute the search the results are wrapped in your document class (Post)</span>
<span class="k">for</span> <span class="n">post</span> <span class="ow">in</span> <span class="n">results</span><span class="p">:</span>
    <span class="k">print</span><span class="p">(</span><span class="n">post</span><span class="o">.</span><span class="n">meta</span><span class="o">.</span><span class="n">score</span><span class="p">,</span> <span class="n">post</span><span class="o">.</span><span class="n">title</span><span class="p">)</span>
			
Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.