1 """contains L{LuceneCollection}, a L{Collection.Collection} based on L{lucene}"""
2 import shutil
3 from lucene import Term, TermQuery
4 from OneOfQuery import OneOfQuery
5
6 import Smarts
7 from LuceneConstants import Constants
8 from grassyknoll.collection import Collection
9 from grassyknoll.lib import Norman
10
11
12
13
15 """a L{Collection.Collection} with L{Smarts}
16
17 This class implements all of the L{Collection.Collection} methods.
18
19 L{Collection.CollectionResult}s returned include a C{__score__} field, a
20 measure of relevance.
21
22 L{Collection.CollectionResultSet}s returned include as metadata:
23 - C{count}: a count of the total number of matches
24
25 @ivar index_dir: the location of the index
26 @type index_dir: string
27
28 @ivar storage_normans: norman name => a Norman consisting
29 L{SmartFieldNorman}s describing how fields should be saved into the index
30 @type storage_normans: dict
31
32 @ivar default_storage_norman: a default L{storage_normans} to be used if
33 no norman is specified for a L{Collection.CollectionDocument}
34 @type default_storage_norman: L{Norman.ObjectNorman}
35 """
36
37 - def __init__(self, index_dir, default_storage_norman, create=False, **storage_normans):
38 """
39 @arg create: create the index if it doesn't exist
40 @type create: bool
41 """
42 assert callable(default_storage_norman)
43 self.default_storage_norman=default_storage_norman
44 self.storage_normans=storage_normans
45 self.storage=Smarts.SmartStorage(index_dir, create)
46
48 return self.storage.reader.numDocs()
49
50 @staticmethod
52 """@returns: a L{lucene.Query} for a single id"""
53 return TermQuery(Term('__id__', id))
54
55 @staticmethod
57 """@returns: a L{lucene.Query} for many ids"""
58 return OneOfQuery('__id__', ids)
59
60 @Collection.addMetaData
68
69 @Collection.addMetaData
82
83 @Collection.addMetaData
85
86 self.delete([doc.id for doc in docs])
87
88
89 for doc in docs:
90 self.storage.insert(self.buildSmartDoc(doc))
91
92 return Collection.CollectionIds([doc.id for doc in docs])
93
94
95
96 @staticmethod
98 """builds fields for a L{Collection.CollectionResult} from a hit
99
100 @rtype: dict
101 """
102
103 d = hit.fields(fields)
104
105 d['__score__'] = hit.score
106 return d
107
108 @Collection.addMetaData
109 - def searchQuery(self, q, start=0, stop=None, fields=None):
110 """search the collection.
111
112 start and stop are interpreted in Python L{slice} sense.
113
114 @arg q: a Lucene query string
115 @type q: unicode
116
117 @arg start: index of first result to return.
118 @type start: int
119
120 @arg stop: index of last+1 result to return.
121 @type stop: int
122
123 @arg fields: a sub-L{set} of fields that should be returned. Defaults
124 to None, meaning all available fields.
125 @type fields: set
126
127 @returns: the results, or None if not found
128 @rtype: L{CollectionResultSet}
129 """
130 hits=self.storage.search(q)
131
132 results=[Collection.CollectionResult(self.__resultFields(h, fields))
133 for h in hits[start:stop]]
134
135
136
137
138
139 return Collection.CollectionResultSet(results, {'count':len(hits)})
140
141 @Collection.addMetaData
145
148
150 "Remove storage directory."
151
152 if self.storage.index_dir is not None:
153 shutil.rmtree(self.storage.index_dir)
154
165
166 -def SmartFieldNorman(store=None, index=None, termvector=None, alltext=None,
167 optional=False, filled=False, prohibited=False):
168 """a L{Norman.FunctionNorman} that generates L{Smarts.SmartField}s
169
170 See L{Smarts.SmartField} and L{Norman.Norman} for parameters.
171 """
172 if store is not None: store=Constants.toConstant(store, 'store')
173 if index is not None: index=Constants.toConstant(index, 'index')
174 if termvector is not None: termvector=Constants.toConstant(termvector, 'termvector')
175 assert alltext is None or isinstance(alltext, bool)
176
177 return Norman.FunctionNorman(Smarts.SmartField, store=store, index=index,
178 termvector=termvector, alltext=alltext,
179 optional=optional, filled=filled, prohibited=prohibited)
180
188
189 -def LuceneNorman(unknown='error', optional=False, filled=False, prohibited=False):
190 """a reasonable default L{Norman.ObjectNorman} for use with L{LuceneCollection}.
191
192 Users should add addtional L{Norman}s as desired.
193 """
194 norman=Norman.ObjectNorman(unknown=unknown, optional=optional,
195 filled=filled, prohibited=prohibited)
196 norman.__id__=InternalFieldNorman()
197 return norman
198