Skip to content

Commit 356a5ec

Browse files
committed
Merge remote-tracking branch 'origin/pr/151'
2 parents bfb08e8 + 1150e12 commit 356a5ec

File tree

3 files changed

+45
-4
lines changed

3 files changed

+45
-4
lines changed

README.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,12 @@ Basic usage looks like:
106106
# correctly.
107107
similar = solr.more_like_this(q='id:doc_2', mltfl='text')
108108
109-
# Finally, you can delete either individual documents...
109+
# Finally, you can delete either individual documents,
110110
solr.delete(id='doc_1')
111111
112+
# also in batches...
113+
solr.delete(id=['doc_1', 'doc_2'])
114+
112115
# ...or all documents.
113116
solr.delete(q='*:*')
114117

pysolr.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -907,7 +907,8 @@ def delete(self, id=None, q=None, commit=True, softCommit=False, waitFlush=None,
907907
Deletes documents.
908908
909909
Requires *either* ``id`` or ``query``. ``id`` is if you know the
910-
specific document id to remove. ``query`` is a Lucene-style query
910+
specific document id to remove. Note that ``id`` can also be a list of
911+
document ids to be deleted. ``query`` is a Lucene-style query
911912
indicating a collection of documents to delete.
912913
913914
Optionally accepts ``commit``. Default is ``True``.
@@ -921,6 +922,7 @@ def delete(self, id=None, q=None, commit=True, softCommit=False, waitFlush=None,
921922
Usage::
922923
923924
solr.delete(id='doc_12')
925+
solr.delete(id=['doc_1', 'doc_3'])
924926
solr.delete(q='*:*')
925927
926928
"""
@@ -929,7 +931,14 @@ def delete(self, id=None, q=None, commit=True, softCommit=False, waitFlush=None,
929931
elif id is not None and q is not None:
930932
raise ValueError('You many only specify "id" OR "q", not both.')
931933
elif id is not None:
932-
m = '<delete><id>%s</id></delete>' % id
934+
if not isinstance(id, (list, set, tuple)):
935+
id = [id]
936+
else:
937+
id = list(filter(None, id))
938+
if id:
939+
m = '<delete>%s</delete>' % ''.join('<id>%s</id>' % i for i in id)
940+
else:
941+
raise ValueError('The list of documents to delete was empty.')
933942
elif q is not None:
934943
m = '<delete><query>%s</query></delete>' % q
935944

tests/test_client.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from __future__ import absolute_import, unicode_literals
33

44
import datetime
5+
import random
56
import unittest
67
from io import StringIO
78
from xml.etree import ElementTree
@@ -704,7 +705,35 @@ def test_delete(self):
704705
self.solr.delete(q='*:*')
705706
self.assertEqual(len(self.solr.search('*:*')), 0)
706707

707-
# Need at least one.
708+
# Test delete() with `id' being a list.
709+
# Solr's ability to delete parent/children docs by id is simply assumed
710+
# and not what's under test here.
711+
def leaf_doc(doc):
712+
return 'price' in doc and NESTED_DOC_KEY not in doc
713+
714+
to_delete_docs = list(filter(leaf_doc, self.docs))
715+
to_delete_ids = [doc['id'] for doc in to_delete_docs]
716+
717+
self.solr.add(to_delete_docs)
718+
self.solr.commit()
719+
720+
leaf_q = 'price:[* TO *]'
721+
self.assertEqual(len(self.solr.search(leaf_q)), len(to_delete_docs))
722+
# Extract a random doc from the list, to later check it wasn't deleted.
723+
graced_doc_id = to_delete_ids.pop(random.randint(0, len(to_delete_ids) - 1))
724+
self.solr.delete(id=to_delete_ids)
725+
# There should be only one left, our graced id
726+
self.assertEqual(len(self.solr.search(leaf_q)), 1)
727+
self.assertEqual(len(self.solr.search('id:%s' % graced_doc_id)), 1)
728+
# Now we can wipe the graced document too. None should be left.
729+
self.solr.delete(id=graced_doc_id)
730+
self.assertEqual(len(self.solr.search(leaf_q)), 0)
731+
732+
# Can't delete when the list of documents is empty
733+
self.assertRaises(ValueError, self.solr.delete, id=[None, None, None])
734+
self.assertRaises(ValueError, self.solr.delete, id=[None])
735+
736+
# Need at least one of either `id' or `q'
708737
self.assertRaises(ValueError, self.solr.delete)
709738
# Can't have both.
710739
self.assertRaises(ValueError, self.solr.delete, id='foo', q='bar')

0 commit comments

Comments
 (0)