mongodb-odm-docs-dash/build.docset/Contents/Resources/Documents/cookbook/simple-search-engine.html
2017-12-01 19:35:11 -08:00

300 lines
18 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Simple Search Engine &mdash; Doctrine MongoDB ODM 1.1.5 documentation</title>
<link rel="stylesheet" href="../_static/bootstrap/css/bootstrap.min.css" type="text/css" />
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../_static/layout.css" type="text/css" />
<link rel="stylesheet" href="../_static/configurationblock.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '1.1.5',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/configurationblock.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/configurationblock.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="../_static/configurationblock.js"></script>
<script src="../_static/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript">
<!--
$(document).ready(function() {
$("#versions").change(function() {
var docsUrl = $(this).val();
window.location.href = docsUrl;
});
});
-->
</script>
<link rel="shortcut icon" href="../_static/doctrine.ico"/>
<link rel="search" title="Search" href="../search.html" />
<link rel="top" title="Doctrine MongoDB ODM 1.1.5 documentation" href="../index.html" />
</head>
<body>
<div id="wrapper">
<div id="header">
<h1 id="h1title"></h1>
<div id="logo">
<a href="http://www.doctrine-project.org/">Doctrine - PHP Database Libraries</a>
</div>
</div>
<div id="nav" class="cls">
<div class="tl cls">
<ul>
<li><a target="_top" href="http://www.doctrine-project.org/">Home</a></li>
<li><a target="_top" href="http://www.doctrine-project.org/about.html">About</a></li>
<li><a target="_top" href="http://www.doctrine-project.org/projects.html">Projects</a></li>
<li><a target="_top" href="http://www.doctrine-project.org/contribute.html">Contribute</a></li>
<li><a target="_top" href="http://www.doctrine-project.org/community.html">Community</a></li>
<li><a target="_top" href="http://www.doctrine-project.org/archive.html">Blog</a></li>
<li><a target="_top" href="http://www.doctrine-project.org/jira">Development</a></li>
</ul>
</div>
</div>
<div id="content" class="cls">
<div class="related">
<h3>Navigation</h3>
<ul>
<li><a href="/">Doctrine Homepage</a> &raquo;</li>
<li><a href="../index.html">Doctrine MongoDB ODM 1.1.5 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" >
<div class="section" id="simple-search-engine">
<h1>Simple Search Engine<a class="headerlink" href="#simple-search-engine" title="Permalink to this headline"></a></h1>
<p>It is very easy to implement a simple keyword search engine with MongoDB. Because of
its flexible schema less nature we can store the keywords we want to search through directly
on the document. MongoDB is capable of indexing the embedded documents so the results are fast
and scalable.</p>
<div class="section" id="sample-model-product">
<h2>Sample Model: Product<a class="headerlink" href="#sample-model-product" title="Permalink to this headline"></a></h2>
<p>Imagine you had a <code class="docutils literal"><span class="pre">Product</span></code> document and you want to search the products by keywords. You can
setup a document like the following with a <code class="docutils literal"><span class="pre">$keywords</span></code> property that is mapped as a collection:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">Product</span>
<span class="p">{</span>
<span class="sd">/** @Id */</span>
<span class="k">private</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$title</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;collection&quot;) @Index */</span>
<span class="k">private</span> <span class="nv">$keywords</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
<span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="working-with-keywords">
<h2>Working with Keywords<a class="headerlink" href="#working-with-keywords" title="Permalink to this headline"></a></h2>
<p>Now, create a product and add some keywords:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$product</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Product</span><span class="p">();</span>
<span class="nv">$product</span><span class="o">-&gt;</span><span class="na">setTitle</span><span class="p">(</span><span class="s1">&#39;Nike Air Jordan 2011&#39;</span><span class="p">);</span>
<span class="nv">$product</span><span class="o">-&gt;</span><span class="na">addKeyword</span><span class="p">(</span><span class="s1">&#39;nike shoes&#39;</span><span class="p">);</span>
<span class="nv">$product</span><span class="o">-&gt;</span><span class="na">addKeyword</span><span class="p">(</span><span class="s1">&#39;jordan shoes&#39;</span><span class="p">);</span>
<span class="nv">$product</span><span class="o">-&gt;</span><span class="na">addKeyword</span><span class="p">(</span><span class="s1">&#39;air jordan&#39;</span><span class="p">);</span>
<span class="nv">$product</span><span class="o">-&gt;</span><span class="na">addKeyword</span><span class="p">(</span><span class="s1">&#39;shoes&#39;</span><span class="p">);</span>
<span class="nv">$product</span><span class="o">-&gt;</span><span class="na">addKeyword</span><span class="p">(</span><span class="s1">&#39;2011&#39;</span><span class="p">);</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">persist</span><span class="p">(</span><span class="nv">$product</span><span class="p">);</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">flush</span><span class="p">();</span>
</pre></div>
</div>
<p>The above example populates the keywords manually but you could very easily write some code which
automatically generates your keywords from a string built by the Product that may include the title,
description and other fields. You could also use a tool like the <a class="reference external" href="http://www.alchemyapi.com">AlchemyAPI</a> if you want to do
some more intelligent keyword extraction.</p>
</div>
<div class="section" id="searching-keywords">
<h2>Searching Keywords<a class="headerlink" href="#searching-keywords" title="Permalink to this headline"></a></h2>
<p>Searching the keywords in the <code class="docutils literal"><span class="pre">Product</span></code> collection is easy! You can run a query like the following
to find documents that have at least one of the keywords:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$keywords</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;nike shoes&#39;</span><span class="p">,</span> <span class="s1">&#39;air jordan&#39;</span><span class="p">);</span>
<span class="nv">$qb</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;Product&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;keywords&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">in</span><span class="p">(</span><span class="nv">$keywords</span><span class="p">);</span>
</pre></div>
</div>
<p>You can make the query more strict by using the <code class="docutils literal"><span class="pre">all()</span></code> method instead of <code class="docutils literal"><span class="pre">in()</span></code>:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$keywords</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;nike shoes&#39;</span><span class="p">,</span> <span class="s1">&#39;air jordan&#39;</span><span class="p">);</span>
<span class="nv">$qb</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;Product&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;keywords&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">all</span><span class="p">(</span><span class="nv">$keywords</span><span class="p">);</span>
</pre></div>
</div>
<p>The above query would only return products that have both of the keywords!</p>
<div class="section" id="user-input">
<h3>User Input<a class="headerlink" href="#user-input" title="Permalink to this headline"></a></h3>
<p>You can easily build keywords from a user search form by exploding whitespace and passing
the results to your query. Here is an example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$queryString</span> <span class="o">=</span> <span class="nv">$_REQUEST</span><span class="p">[</span><span class="s1">&#39;q&#39;</span><span class="p">];</span>
<span class="nv">$keywords</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="nv">$queryString</span><span class="p">);</span>
<span class="nv">$qb</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;Product&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;keywords&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">all</span><span class="p">(</span><span class="nv">$keywords</span><span class="p">);</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="embedded-documents">
<h2>Embedded Documents<a class="headerlink" href="#embedded-documents" title="Permalink to this headline"></a></h2>
<p>If you want to use an embedded document instead of just an array then you can. It will allow you to store
additional information with each keyword, like its weight.</p>
<div class="section" id="definition">
<h3>Definition<a class="headerlink" href="#definition" title="Permalink to this headline"></a></h3>
<p>You can setup a <code class="docutils literal"><span class="pre">Keyword</span></code> document like the following:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/** @EmbeddedDocument */</span>
<span class="k">class</span> <span class="nc">Keyword</span>
<span class="p">{</span>
<span class="sd">/** @Field(type=&quot;string&quot;) @Index */</span>
<span class="k">private</span> <span class="nv">$keyword</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;int&quot;) */</span>
<span class="k">private</span> <span class="nv">$weight</span><span class="p">;</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">__construct</span><span class="p">(</span><span class="nv">$keyword</span><span class="p">,</span> <span class="nv">$weight</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">keyword</span> <span class="o">=</span> <span class="nv">$keyword</span><span class="p">;</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">weight</span> <span class="o">=</span> <span class="nv">$weight</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Now you can embed the <code class="docutils literal"><span class="pre">Keyword</span></code> document many times in the <code class="docutils literal"><span class="pre">Product</span></code>:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">Product</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="sd">/** @EmbedMany(targetDocument=&quot;Keyword&quot;) */</span>
<span class="k">private</span> <span class="nv">$keywords</span><span class="p">;</span>
<span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
<p>With the new embedded document to add a keyword to a <code class="docutils literal"><span class="pre">Product</span></code> the API is a little different,
you would have to do the following:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$product</span><span class="o">-&gt;</span><span class="na">addKeyword</span><span class="p">(</span><span class="k">new</span> <span class="nx">Keyword</span><span class="p">(</span><span class="s1">&#39;nike shoes&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">));</span>
</pre></div>
</div>
<p>This is a very basic search engine example and can work for many small and simple applications. If you
need better searching functionality you can look at integrating something like <a class="reference external" href="http://lucene.apache.org/solr">Solr</a> in your project.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<div id="searchbox" style="">
<h3>Search</h3>
<form class="search" action="http://readthedocs.org/search/project/" method="get">
<input type="text" name="q" size="18">
<input type="submit" value="Go">
<input type="hidden" name="selected_facets" value="project:">
</form>
</div>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Simple Search Engine</a><ul>
<li><a class="reference internal" href="#sample-model-product">Sample Model: Product</a></li>
<li><a class="reference internal" href="#working-with-keywords">Working with Keywords</a></li>
<li><a class="reference internal" href="#searching-keywords">Searching Keywords</a><ul>
<li><a class="reference internal" href="#user-input">User Input</a></li>
</ul>
</li>
<li><a class="reference internal" href="#embedded-documents">Embedded Documents</a><ul>
<li><a class="reference internal" href="#definition">Definition</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/cookbook/simple-search-engine.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy; Copyright 2013, Doctrine Project Team.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.6.2.
<br/>
<a target="_BLANK" href="http://www.servergrove.com"><img src="http://www.doctrine-project.org/_static/servergrove.jpg" /></a> <br/><br/>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick" />
<input type="hidden" name="hosted_button_id" value="BAE2E3XANQ77Y" />
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" />
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
</form>
</div>
</div>
<div id="bot-rcnr">
<div class="tl"><!-- corner --></div>
</div>
</div>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-288343-7";
urchinTracker();
</script>
<a class="githublink" href="http://github.com/doctrine"><img src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png" alt="Fork me on GitHub"></a>
</body>
</html>