Skip to content

Commit d701847

Browse files
committed
Support for nested documents (closes #210)
Thanks to @efagerberg, @msokolov, and @thisisstephenbetts for the patch!
1 parent 1d03382 commit d701847

File tree

3 files changed

+45
-1
lines changed

3 files changed

+45
-1
lines changed

README.rst

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ interface that queries the server and returns results based on the query.
77

88
.. _`Apache Solr`: http://lucene.apache.org/solr/
99

10-
1110
Status
1211
======
1312

@@ -64,12 +63,21 @@ Basic usage looks like:
6463
{
6564
"id": "doc_2",
6665
"title": "The Banana: Tasty or Dangerous?",
66+
"_doc": [
67+
{ "id": "child_doc_1", "title": "peel" },
68+
{ "id": "child_doc_2", "title": "seed" },
69+
]
6770
},
6871
])
6972
7073
# Note that the add method has commit=True by default, so this is
7174
# immediately committed to your index.
7275
76+
# You can index a parent/child document relationship by
77+
# associating a list of child documents with the special key '_doc'. This
78+
# is helpful for queries that join together conditions on children and parent
79+
# documents.
80+
7381
# Later, searching is easy. In the simple case, just a plain Lucene-style
7482
# query is fine.
7583
results = solr.search('bananas')

pysolr.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,11 @@ def _build_doc(self, doc, boost=None, fieldUpdates=None):
824824
if self._is_null_value(bit):
825825
continue
826826

827+
if key == '_doc':
828+
child = self._build_doc(bit, boost)
829+
doc_elem.append(child)
830+
continue
831+
827832
attrs = {'name': key}
828833

829834
if fieldUpdates and key in fieldUpdates:

tests/test_client.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,37 @@ def test__build_doc(self):
544544
self.assertTrue('<field name="id">doc_1</field>' in doc_xml)
545545
self.assertEqual(len(doc_xml), 152)
546546

547+
def test__build_doc_with_sub_docs(self):
548+
sub_docs = [
549+
{
550+
'id': 'sub_doc_1',
551+
'title': 'Example sub doc ☃ 1',
552+
'price': 1.59,
553+
'popularity': 4
554+
},
555+
{
556+
'id': 'sub_doc_2',
557+
'title': 'Example sub doc ☃ 2',
558+
'price': 21.13,
559+
'popularity': 1
560+
},
561+
]
562+
doc = {
563+
'id': 'doc_1',
564+
'title': 'Example doc ☃ 1',
565+
'price': 12.59,
566+
'popularity': 10,
567+
'_doc': sub_docs
568+
}
569+
doc_xml = self.solr._build_doc(doc)
570+
self.assertEqual(doc_xml.find("*[@name='id']").text, doc['id'])
571+
572+
children_docs = doc_xml.findall('doc')
573+
self.assertEqual(len(children_docs), len(sub_docs))
574+
575+
self.assertEqual(children_docs[0].find("*[@name='id']").text, sub_docs[0]['id'])
576+
self.assertEqual(children_docs[1].find("*[@name='id']").text, sub_docs[1]['id'])
577+
547578
def test_add(self):
548579
self.assertEqual(len(self.solr.search('doc')), 3)
549580
self.assertEqual(len(self.solr.search('example')), 2)

0 commit comments

Comments
 (0)