Commits

Matt Chaput  committed 5ee16ed

Fixed bugs in NestedDocument query implementation, added first test.

  • Participants
  • Parent commits 12ed026
  • Branches nested

Comments (0)

Files changed (4)

File src/whoosh/filedb/multiproc.py

         if len(self.docbuffer) >= self.bufferlimit:
             self._enqueue()
 
+    def add_document_group(self, docs):
+        # Add the documents to the doc buffer all at once
+        self.docbuffer.extend(docs)
+        # THEN check if the buffer is too big
+        if len(self.docbuffer) >= self.bufferlimit:
+            self._enqueue()
+
     def commit(self, **kwargs):
         try:
             # index the remaining stuff in self.docbuffer

File src/whoosh/query.py

     def matcher(self, searcher):
         comb = searcher._filter_to_comb(self.parents)
         m = self.child.matcher(searcher)
-        return self.NestedDocumentMatcher(comb, m)
+        return self.NestedDocumentMatcher(comb, m, self.score_fn)
 
     class NestedDocumentMatcher(Matcher):
-        def __init__(self, comb, child):
-            WrappingMatcher.__init__(self, child)
+        def __init__(self, comb, child, score_fn):
             self.comb = comb
+            self.child = child
+            self.score_fn = score_fn
             self._gather()
 
+        def is_active(self):
+            return self._nextdoc is not None
+
         def supports_block_quality(self):
             return False
 
                    and self._parent(child.id()) == parent):
                 scores.append(child.score())
                 child.next()
-            self._nextwt = self.score_fn(scores)
+            self._nextscore = self.score_fn(scores)
 
         def id(self):
             return self._nextdoc
             self._gather()
 
         def next(self):
-            if not self.child.is_active():
-                from whoosh.matching import ReadTooFar
+            if self.child.is_active():
+                self._gather()
+            else:
+                if self._nextdoc is None:
+                    from whoosh.matching import ReadTooFar
 
-                raise ReadTooFar
-
-            self._gather()
+                    raise ReadTooFar
+                else:
+                    self._nextdoc = None
 
         def skip_to(self, id):
             self.child.skip_to(id)

File src/whoosh/writing.py

 
         # Delete the set of documents matching the unique terms
         unique_fields = self._unique_fields(fields)
-        with self.searcher() as s:
-            for docnum in s._find_unique([(name, fields[name])
-                                          for name in unique_fields]):
-                self.delete_document(docnum)
+        if unique_fields:
+            with self.searcher() as s:
+                for docnum in s._find_unique([(name, fields[name])
+                                              for name in unique_fields]):
+                    self.delete_document(docnum)
 
         # Add the given fields
         self.add_document(**fields)
 
+    def add_document_group(self, docs):
+        for doc in docs:
+            self.add_document(**doc)
+
+    def update_document_group(self, docs):
+        for doc in docs:
+            self.update_document(**doc)
+
     def commit(self):
         """Finishes writing and unlocks the index.
         """

File tests/test_indexing.py

     with ix.searcher() as s:
         r = s.search(query.Term("a", "alfa"))
         assert_equal([hit["id"] for hit in r], [1, 0, 3, 2])
+
+def test_nested():
+    schema = fields.Schema(name=fields.ID(stored=True), type=fields.ID,
+                           part=fields.ID, price=fields.NUMERIC)
+    ix = RamStorage().create_index(schema)
+    with ix.writer() as w:
+        w.add_document(name=u("iPad"), type=u("product"))
+        w.add_document(part=u("screen"), price=100)
+        w.add_document(part=u("battery"), price=50)
+        w.add_document(part=u("case"), price=20)
+
+        w.add_document(name=u("iPhone"), type=u("product"))
+        w.add_document(part=u("screen"), price=60)
+        w.add_document(part=u("battery"), price=30)
+        w.add_document(part=u("case"), price=10)
+
+        w.add_document(name=u("Mac mini"), type=u("product"))
+        w.add_document(part=u("hard drive"), price=50)
+        w.add_document(part=u("case"), price=50)
+
+    with ix.searcher() as s:
+        price = s.schema["price"]
+
+        pq = query.Term("type", "product")
+        cq = query.Term("price", price.to_text(50))
+        q = query.NestedDocument(pq, cq)
+
+        r = s.search(q)
+        assert_equal(sorted([hit["name"] for hit in r]), ["Mac mini", "iPad"])
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+