Apache

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
  • MultiSegmentQueryFilter enhancement for interactive indexes?

    10 answers - 1154 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg Add To My Reddit

    I thought of a possible enhancement - before I go down the road, I am
    looking for some input form the community?
    Currently, the QueryFilter caches the bits base upon the IndexReader.
    The problem with this is small incremental changes to the index
    invalidate the cache.
    What if instead the filter determined that the underlying IndexReader
    was a MultiReader and then maintained a bitset for each reader,
    combining them in bits() when requested. The filter could check if
    any of the underlying readers were the different (removed or added)
    and then just create a new bitset for that reader. With the new non-
    bit set filter implementations this could be even more memory
    efficient since the bitsets would not need to be combined into a
    single bitset.
    With the previous work on "reopen" so that segments are reused, this
    would allow filters to be far more useful in a highly interactive
    environment.
    What do you think?
    To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org
  • No.1 | | 2312 bytes | |

    I'm no segments/MultiReader expert, but your idea sounds good to me it
    seems like it would certainly work in the "new segments" situation.

    thing i don't see you mention is dealing with deletions i'm not
    sure if deleting documents cause the version number of an IndexReader to
    change or not (if it does your job is easy) but even if it doesn't I'm
    guessing you could say that if hasDeletions() returns true, you have to
    assume you need to invalidate your cached bits (worst case scenerio you
    are invalidating the cache as often as it is now)

    : Date: Fri, 7 Jul 2006 00:32:54 -0500
    : From: robert engels <rengels (AT) ix (DOT) netcom.com>
    : Reply-To: java-dev (AT) lucene (DOT) apache.org
    : To: Lucene-Dev <java-dev (AT) lucene (DOT) apache.org>
    : Subject: MultiSegmentQueryFilter enhancement for interactive indexes?
    :
    : I thought of a possible enhancement - before I go down the road, I am
    : looking for some input form the community?
    :
    : Currently, the QueryFilter caches the bits base upon the IndexReader.
    :
    : The problem with this is small incremental changes to the index
    : invalidate the cache.
    :
    : What if instead the filter determined that the underlying IndexReader
    : was a MultiReader and then maintained a bitset for each reader,
    : combining them in bits() when requested. The filter could check if
    : any of the underlying readers were the different (removed or added)
    : and then just create a new bitset for that reader. With the new non-
    : bit set filter implementations this could be even more memory
    : efficient since the bitsets would not need to be combined into a
    : single bitset.
    :
    : With the previous work on "reopen" so that segments are reused, this
    : would allow filters to be far more useful in a highly interactive
    : environment.
    :
    : What do you think?
    :
    :
    :
    :
    :
    :
    :
    : To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    : For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org
    :

    -Hoss

    To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org
  • No.2 | | 1003 bytes | |

    7/7/06, robert engels <rengels (AT) ix (DOT) netcom.comwrote:
    Exactly. I have been watching to see how the new filer interface
    works out for 2.0. I am still not certain why it is so involved.

    I still think

    interface Filter {
    boolean include(int doc);
    int nextInclude(int doc);
    }

    should suffice.

    It depends on how the interface will be used and the capabilities of
    the underlying implementation.
    Paul's sorted vint list is good on space, but it doesn't do random access well.
    Solr's HashDocSet offers very fast random access, but it doesn't do
    sequential access.
    A BitSet does both, but it's always big.
    There are many other possible implementations & tradeoffs, but you get
    the idea
    -Yonik
    Solr, the open-source Lucene search server

    To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org
  • No.3 | | 3014 bytes | |

    This might be even better in conjunction with moving away from BitSet
    to some sort of interface like DocNrSkipper that way you would
    never have to combine the filters into a single BitSet.

    -Yonik
    Solr, the open-source Lucene search server

    7/7/06, robert engels <rengels (AT) ix (DOT) netcom.comwrote:
    I implemented it and it works great. I didn't worry about the
    deletions since by the time a filter is used the deleted documents
    are already removed by the query. The only problem that arose out of
    this was for things like the ConstantScoreQuery (which uses a filter)
    - I needed to modify this query to ignore deleted documents.

    Now I have incremental cached filters - the query performance is
    going through the roof.
    >
    >
    >

    Jul 7, 2006, at 2:47 PM, Chris Hostetter wrote:
    --
    I'm no segments/MultiReader expert, but your idea sounds good to
    me it
    seems like it would certainly work in the "new segments" situation.

    thing i don't see you mention is dealing with deletions i'm
    not
    sure if deleting documents cause the version number of an
    IndexReader to
    change or not (if it does your job is easy) but even if it doesn't I'm
    guessing you could say that if hasDeletions() returns true, you
    have to
    assume you need to invalidate your cached bits (worst case scenerio
    you
    are invalidating the cache as often as it is now)
    --
    : Date: Fri, 7 Jul 2006 00:32:54 -0500
    : From: robert engels <rengels (AT) ix (DOT) netcom.com>
    : Reply-To: java-dev (AT) lucene (DOT) apache.org
    : To: Lucene-Dev <java-dev (AT) lucene (DOT) apache.org>
    : Subject: MultiSegmentQueryFilter enhancement for interactive
    indexes?
    :
    : I thought of a possible enhancement - before I go down the road,
    I am
    : looking for some input form the community?
    :
    : Currently, the QueryFilter caches the bits base upon the
    IndexReader.
    :
    : The problem with this is small incremental changes to the index
    : invalidate the cache.
    :
    : What if instead the filter determined that the underlying
    IndexReader
    : was a MultiReader and then maintained a bitset for each reader,
    : combining them in bits() when requested. The filter could check if
    : any of the underlying readers were the different (removed or added)
    : and then just create a new bitset for that reader. With the new non-
    : bit set filter implementations this could be even more memory
    : efficient since the bitsets would not need to be combined into a
    : single bitset.
    :
    : With the previous work on "reopen" so that segments are reused, this
    : would allow filters to be far more useful in a highly interactive
    : environment.
    :
    : What do you think?

    To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org
  • No.4 | | 3959 bytes | |

    Exactly. I have been watching to see how the new filer interface
    works out for 2.0. I am still not certain why it is so involved.

    I still think

    interface Filter {
    boolean include(int doc);
    int nextInclude(int doc);
    }

    should suffice.

    Jul 7, 2006, at 9:53 PM, Yonik Seeley wrote:

    This might be even better in conjunction with moving away from BitSet
    to some sort of interface like DocNrSkipper that way you would
    never have to combine the filters into a single BitSet.
    --
    -Yonik
    Solr, the open-source Lucene
    search server

    7/7/06, robert engels <rengels (AT) ix (DOT) netcom.comwrote:
    >I implemented it and it works great. I didn't worry about the
    >deletions since by the time a filter is used the deleted documents
    >are already removed by the query. The only problem that arose out of
    >this was for things like the ConstantScoreQuery (which uses a filter)
    >- I needed to modify this query to ignore deleted documents.
    >>

    >Now I have incremental cached filters - the query performance is
    >going through the roof.
    >>
    >>
    >>

    >Jul 7, 2006, at 2:47 PM, Chris Hostetter wrote:
    >>
    >>

    >I'm no segments/MultiReader expert, but your idea sounds good to
    >me it
    >seems like it would certainly work in the "new segments" situation.
    >>

    >thing i don't see you mention is dealing with deletions i'm
    >not
    >sure if deleting documents cause the version number of an
    >IndexReader to
    >change or not (if it does your job is easy) but even if it
    >doesn't I'm
    >guessing you could say that if hasDeletions() returns true, you
    >have to
    >assume you need to invalidate your cached bits (worst case scenerio
    >you
    >are invalidating the cache as often as it is now)
    >>
    >>

    >: Date: Fri, 7 Jul 2006 00:32:54 -0500
    >: From: robert engels <rengels (AT) ix (DOT) netcom.com>
    >: Reply-To: java-dev (AT) lucene (DOT) apache.org
    >: To: Lucene-Dev <java-dev (AT) lucene (DOT) apache.org>
    >: Subject: MultiSegmentQueryFilter enhancement for interactive
    >indexes?
    >:
    >: I thought of a possible enhancement - before I go down the road,
    >I am
    >: looking for some input form the community?
    >:
    >: Currently, the QueryFilter caches the bits base upon the
    >IndexReader.
    >:
    >: The problem with this is small incremental changes to the index
    >: invalidate the cache.
    >:
    >: What if instead the filter determined that the underlying
    >IndexReader
    >: was a MultiReader and then maintained a bitset for each reader,
    >: combining them in bits() when requested. The filter could
    >check if
    >: any of the underlying readers were the different (removed or
    >added)
    >: and then just create a new bitset for that reader. With the
    >new non-
    >: bit set filter implementations this could be even more memory
    >: efficient since the bitsets would not need to be combined into a
    >: single bitset.
    >:
    >: With the previous work on "reopen" so that segments are
    >reused, this
    >: would allow filters to be far more useful in a highly interactive
    >: environment.
    >:
    >: What do you think?
    >


    To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org

    To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org
  • No.5 | | 3064 bytes | |

    I implemented it and it works great. I didn't worry about the
    deletions since by the time a filter is used the deleted documents
    are already removed by the query. The only problem that arose out of
    this was for things like the ConstantScoreQuery (which uses a filter)
    - I needed to modify this query to ignore deleted documents.

    Now I have incremental cached filters - the query performance is
    going through the roof.

    Jul 7, 2006, at 2:47 PM, Chris Hostetter wrote:

    I'm no segments/MultiReader expert, but your idea sounds good to
    me it
    seems like it would certainly work in the "new segments" situation.

    thing i don't see you mention is dealing with deletions i'm
    not
    sure if deleting documents cause the version number of an
    IndexReader to
    change or not (if it does your job is easy) but even if it doesn't I'm
    guessing you could say that if hasDeletions() returns true, you
    have to
    assume you need to invalidate your cached bits (worst case scenerio
    you
    are invalidating the cache as often as it is now)
    --
    : Date: Fri, 7 Jul 2006 00:32:54 -0500
    : From: robert engels <rengels (AT) ix (DOT) netcom.com>
    : Reply-To: java-dev (AT) lucene (DOT) apache.org
    : To: Lucene-Dev <java-dev (AT) lucene (DOT) apache.org>
    : Subject: MultiSegmentQueryFilter enhancement for interactive
    indexes?
    :
    : I thought of a possible enhancement - before I go down the road,
    I am
    : looking for some input form the community?
    :
    : Currently, the QueryFilter caches the bits base upon the
    IndexReader.
    :
    : The problem with this is small incremental changes to the index
    : invalidate the cache.
    :
    : What if instead the filter determined that the underlying
    IndexReader
    : was a MultiReader and then maintained a bitset for each reader,
    : combining them in bits() when requested. The filter could check if
    : any of the underlying readers were the different (removed or added)
    : and then just create a new bitset for that reader. With the new non-
    : bit set filter implementations this could be even more memory
    : efficient since the bitsets would not need to be combined into a
    : single bitset.
    :
    : With the previous work on "reopen" so that segments are reused, this
    : would allow filters to be far more useful in a highly interactive
    : environment.
    :
    : What do you think?
    :
    :
    :
    :
    :
    :
    :

    : To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    : For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org
    :
    >
    >
    >

    -Hoss
    --

    To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org

    To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org
  • No.6 | | 1521 bytes | |

    Agreed. The interface I proposed supports both sequential and random
    access to the filter - hiding the implementation.

    Jul 7, 2006, at 10:10 PM, Yonik Seeley wrote:

    7/7/06, robert engels <rengels (AT) ix (DOT) netcom.comwrote:
    >Exactly. I have been watching to see how the new filer interface
    >works out for 2.0. I am still not certain why it is so involved.
    >>

    >I still think
    >>

    >interface Filter {
    >boolean include(int doc);
    >int nextInclude(int doc);
    >}
    >>

    >should suffice.
    >

    It depends on how the interface will be used and the capabilities of
    the underlying implementation.
    Paul's sorted vint list is good on space, but it doesn't do random
    access well.
    Solr's HashDocSet offers very fast random access, but it doesn't do
    sequential access.
    A BitSet does both, but it's always big.
    There are many other possible implementations & tradeoffs, but you get
    the idea

    -Yonik
    Solr, the open-source Lucene
    search server

    To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org

    To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org
  • No.7 | | 1273 bytes | |

    Saturday 08 July 2006 05:44, robert engels wrote:
    Agreed. The interface I proposed supports both sequential and random
    access to the filter - hiding the implementation.

    For query searching, random access to a Filter is only needed
    in the forward direction, e.g. by nextInclude(docNr) or skipTo(docNr).

    As for why it's so involved:

    Making a "rewritten" Filter work more like a Scorer has the advantage
    that combinations of filters can (also) be evaluated using the same
    mechanisms as currently existing for Scorers. For this, some additions
    to the existing code will be needed, like adding an
    add(Filter, BooleanC) to BooleanQuery, and a similar
    addition of a Matcher (proposed superclass of Scorer to "rewrite" a
    Filter to) to some of the underlying scorers.
    Such occurrences of filters are only "must" and "must not", "should"
    doesn't make sense because there is no score value.

    Also, it makes sense to have an explain() method for a "rewritten"
    Filter, because it can be for searching a query.

    Regards,
    Paul Elschot

    To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org
  • No.8 | | 3167 bytes | |

    Attached is the incremental updating QueryFilter. The MyMultiReader
    class is a basic extension of MultiReader that allows access to the
    underlying IndexReaders.

    this also requires that "reopen" be implemented so that
    SegmentReaders for unchanged segments remain the same through the open.

    Robert

    Jul 8, 2006, at 7:14 AM, robert engels wrote:

    Is that really necessary for a filter? It seems that a filter
    implies efficiency over a "scoring", and that filters should be
    able to be evaluated in a chained (or priority queue) fashion
    fairly efficiently without any need for 'rewrites".

    With the new incremental updates of a filter (based upon a query)
    it seems that the newly proposed filtering could be far less
    efficient.

    I think a filter change that just removes the BitSet dependency is
    all that is needed, and anything else is overkill, but I admit I am
    probably missing something here.

    If these changes will eventually allow for efficient filtering
    based upon non-indexed stored fields I am all for it.

    Jul 8, 2006, at 2:24 AM, Paul Elschot wrote:
    >
    >Saturday 08 July 2006 05:44, robert engels wrote:

    Agreed. The interface I proposed supports both sequential and random
    access to the filter - hiding the implementation.
    >>

    >For query searching, random access to a Filter is only needed
    >in the forward direction, e.g. by nextInclude(docNr) or skipTo
    >(docNr).
    >>

    >As for why it's so involved:
    >>

    >Making a "rewritten" Filter work more like a Scorer has the advantage
    >that combinations of filters can (also) be evaluated using the same
    >mechanisms as currently existing for Scorers. For this, some
    >additions
    >to the existing code will be needed, like adding an
    >add(Filter, BooleanC) to BooleanQuery, and a similar
    >addition of a Matcher (proposed superclass of Scorer to "rewrite" a
    >Filter to) to some of the underlying scorers.
    >Such occurrences of filters are only "must" and "must not", "should"
    >doesn't make sense because there is no score value.
    >>

    >Also, it makes sense to have an explain() method for a "rewritten"
    >Filter, because it can be for searching a query.
    >>

    >Regards,
    >Paul Elschot
    >>

    >
    >To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    >For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org
    >>

    >
    >


    To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org

    To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org
  • No.9 | | 2240 bytes | |

    Is that really necessary for a filter? It seems that a filter implies
    efficiency over a "scoring", and that filters should be able to be
    evaluated in a chained (or priority queue) fashion fairly efficiently
    without any need for 'rewrites".

    With the new incremental updates of a filter (based upon a query) it
    seems that the newly proposed filtering could be far less efficient.

    I think a filter change that just removes the BitSet dependency is
    all that is needed, and anything else is overkill, but I admit I am
    probably missing something here.

    If these changes will eventually allow for efficient filtering based
    upon non-indexed stored fields I am all for it.

    Jul 8, 2006, at 2:24 AM, Paul Elschot wrote:

    Saturday 08 July 2006 05:44, robert engels wrote:
    >Agreed. The interface I proposed supports both sequential and random
    >access to the filter - hiding the implementation.
    >

    For query searching, random access to a Filter is only needed
    in the forward direction, e.g. by nextInclude(docNr) or skipTo(docNr).

    As for why it's so involved:

    Making a "rewritten" Filter work more like a Scorer has the advantage
    that combinations of filters can (also) be evaluated using the same
    mechanisms as currently existing for Scorers. For this, some additions
    to the existing code will be needed, like adding an
    add(Filter, BooleanC) to BooleanQuery, and a similar
    addition of a Matcher (proposed superclass of Scorer to "rewrite" a
    Filter to) to some of the underlying scorers.
    Such occurrences of filters are only "must" and "must not", "should"
    doesn't make sense because there is no score value.

    Also, it makes sense to have an explain() method for a "rewritten"
    Filter, because it can be for searching a query.

    Regards,
    Paul Elschot

    To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org

    To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org
  • No.10 | | 5630 bytes | |

    Robert,

    Thanks for your questions, things are beginning to fall into place
    (see ):

    Saturday 08 July 2006 14:14, robert engels wrote:
    Is that really necessary for a filter? It seems that a filter implies
    efficiency over a "scoring", and that filters should be able to be

    The proposed Matcher is superclass of Scorer formed by leaving
    out all the methods dealing with score values.

    evaluated in a chained (or priority queue) fashion fairly efficiently

    The current DisjunctionSumScorer has a priority queue. I have to say
    that I did not yet consider a filter clause to a boolean query that is
    based on an disjunction of filters: in this case the "should" occurrence
    makes sense, but calling it a query is overdoing it, the disjunction
    would be a Filter itself.

    In principle, it is possible to evaluate a disjunction over filters during a
    query search, and it might even make sense when the disjunction is
    skipTo'd into infrequently as one of the required clauses in a boolean query.
    I have no idea whether this would be useful in practice.

    Also, in the same way as for top level disjunction queries, for filters
    there are more efficient methods of dealing with top level disjunction
    than a priority queue, see for example RangeFilter that collects
    all matching docs in a BitSet by iterating the TermScorers in the range
    one by one.

    The distinction between top level evaluation and nested evaluation is
    in the proposed Matcher: it has a match(MatchCollector) method for the top
    level, and the doc(), next() and skipTo() can be used for nested evaluation.
    The same distinction exists in Scorer: score(HitCollector, ) and roughly
    the rest.

    without any need for 'rewrites".

    Rewriting of a query is a way to make an association between
    a query and one or more index readers. The same association is currently
    present for a Filter in the bits(IndexReader) method, proposed
    to be deprecated.
    Perhaps the proposed getMatcher(IndexReader) method should
    be called Filter.rewrite(IndexReader), just as Query.rewrite(IndexReader).

    With the new incremental updates of a filter (based upon a query) it
    seems that the newly proposed filtering could be far less efficient.

    A Filter can be composed in the same way as an IndexReader can use
    multiple segments. Also, document deletion in a segment is currently done
    by a special purpose bit set.
    For incremental updates, the "rewriting" of a filter could be limited to the
    filter component associated with the newly added segment(s).

    I think a filter change that just removes the BitSet dependency is
    all that is needed, and anything else is overkill, but I admit I am

    I thought so, too. But then I realized that there are many things shared
    between current Scorers and Filters. These things are dealing mostly
    with matching and not at all with scoring.

    probably missing something here.

    Perhaps a method to provide a complete Explanation of why a document
    matches, or does not match, a filtered query?

    If these changes will eventually allow for efficient filtering based
    upon non-indexed stored fields I am all for it.

    For the non indexed case, there is no choice but to read all stored data
    and evaluate a boolean function on the field of each document.
    I think the only efficiency to be gained there is in reading the stored
    fields, but iirc that has been fixed.
    For the indexed case a TermScorer is a Scorer is a proposed Matcher.
    The norms can already be left out, so the only things "left to be left out"
    are the term frequencies and positions. that is done there is no
    more need to use a non-indexed stored field for filtering, because an
    indexed-only field would always be more efficient in indexed data size.

    Regards,
    Paul Elschot

    Jul 8, 2006, at 2:24 AM, Paul Elschot wrote:

    Saturday 08 July 2006 05:44, robert engels wrote:
    >Agreed. The interface I proposed supports both sequential and random
    >access to the filter - hiding the implementation.
    >

    For query searching, random access to a Filter is only needed
    in the forward direction, e.g. by nextInclude(docNr) or skipTo(docNr).

    As for why it's so involved:

    Making a "rewritten" Filter work more like a Scorer has the advantage
    that combinations of filters can (also) be evaluated using the same
    mechanisms as currently existing for Scorers. For this, some additions
    to the existing code will be needed, like adding an
    add(Filter, BooleanC) to BooleanQuery, and a similar
    addition of a Matcher (proposed superclass of Scorer to "rewrite" a
    Filter to) to some of the underlying scorers.
    Such occurrences of filters are only "must" and "must not", "should"
    doesn't make sense because there is no score value.

    Also, it makes sense to have an explain() method for a "rewritten"
    Filter, because it can be for searching a query.

    Regards,
    Paul Elschot

    To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org

    To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org

    To unsubscribe, e-mail: java-dev-unsubscribe (AT) lucene (DOT) apache.org
    For additional commands, e-mail: java-dev-help (AT) lucene (DOT) apache.org

Re: MultiSegmentQueryFilter enhancement for interactive indexes?


max 4000 letters.
Your nickname that display:
In order to stop the spam: 7 + 6 =
QUESTION ON "Apache"

EMSDN.COM