Skip to content

dedup order_by by value and id#959

Merged
joein merged 3 commits into
devfrom
dedup-order-by
Apr 24, 2025
Merged

dedup order_by by value and id#959
joein merged 3 commits into
devfrom
dedup-order-by

Conversation

@coszio
Copy link
Copy Markdown
Contributor

@coszio coszio commented Apr 22, 2025

In congruence with qdrant/qdrant#6233, we deduplicate same value and id points

@coszio coszio requested a review from joein April 22, 2025 22:37
@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 22, 2025

Deploy Preview for poetic-froyo-8baba7 ready!

Name Link
🔨 Latest commit d80024e
🔍 Latest deploy log https://app.netlify.com/sites/poetic-froyo-8baba7/deploys/680a0e9f6265cd0008e67c2e
😎 Deploy Preview https://deploy-preview-959--poetic-froyo-8baba7.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2025

📝 Walkthrough

Walkthrough

The update modifies the _scroll_by_value method within the LocalCollection class in the qdrant_client/local/local_collection.py file. The change introduces a deduplication step by adding a set called seen_tuples to track encountered (value, external_id) pairs during iteration. As the method processes value_and_ids, it checks whether each (value, external_id) tuple has already been seen. If it has, the record is skipped; otherwise, the tuple is added to the set and the record is appended to the results. Additionally, the order_value field is set to the current value for each appended record.

In the test suite under tests/congruence_tests/test_scroll_order_by.py, the scroll_all_with_key function is updated to use record.order_value for scrolling logic and to handle payload values that may be lists by converting and comparing each item appropriately. A new helper function scroll_all_integer_arrays is added to scroll using the "integer_array" key. A new test, test_scroll_duplicated_values, is introduced to verify consistent scrolling behavior across local, HTTP, and gRPC clients with integer array payloads. No changes are made to exported or public entity signatures.

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coszio
Copy link
Copy Markdown
Contributor Author

coszio commented Apr 23, 2025

I need to check the errors in tests

@coszio coszio marked this pull request as draft April 23, 2025 17:59
@joein
Copy link
Copy Markdown
Member

joein commented Apr 24, 2025

I need to check the errors in tests

it's just float precision, isn't it?

@joein
Copy link
Copy Markdown
Member

joein commented Apr 24, 2025

I ran a simple test and results seem to be the same

from qdrant_client import QdrantClient, models


cl = QdrantClient()

if cl.collection_exists("test"):
    cl.delete_collection("test")

cl.create_collection(
    "test", vectors_config=models.VectorParams(size=2, distance=models.Distance.COSINE)
)

cl.upsert(
    "test",
    points=[
        models.PointStruct(
            id=1,
            vector=[0.2, 0.3],
            payload={"a": [1, 2, 3, 4]},
        ),
        models.PointStruct(id=2, vector=[0.3, 0.2], payload={"a": [2, 3, 4, 5]}),
    ],
)
cl.create_payload_index("test", "a", models.PayloadSchemaType.INTEGER, wait=True)
import pprint

pprint.pprint(cl.query_points("test", query=models.OrderByQuery(order_by="a")).points)

Output:

[ScoredPoint(id=1, version=0, score=0.0, payload={'a': [1, 2, 3, 4]}, vector=None, shard_key=None, order_value=1),
 ScoredPoint(id=2, version=0, score=0.0, payload={'a': [2, 3, 4, 5]}, vector=None, shard_key=None, order_value=2),
 ScoredPoint(id=1, version=0, score=0.0, payload={'a': [1, 2, 3, 4]}, vector=None, shard_key=None, order_value=2),
 ScoredPoint(id=2, version=0, score=0.0, payload={'a': [2, 3, 4, 5]}, vector=None, shard_key=None, order_value=3),
 ScoredPoint(id=1, version=0, score=0.0, payload={'a': [1, 2, 3, 4]}, vector=None, shard_key=None, order_value=3),
 ScoredPoint(id=2, version=0, score=0.0, payload={'a': [2, 3, 4, 5]}, vector=None, shard_key=None, order_value=4),
 ScoredPoint(id=1, version=0, score=0.0, payload={'a': [1, 2, 3, 4]}, vector=None, shard_key=None, order_value=4),
 ScoredPoint(id=2, version=0, score=0.0, payload={'a': [2, 3, 4, 5]}, vector=None, shard_key=None, order_value=5)]

And `QdrantClient(":memory:") output with this PR is:

[ScoredPoint(id=1, version=0, score=0.0, payload={'a': [1, 2, 3, 4]}, vector=None, shard_key=None, order_value=None),
 ScoredPoint(id=1, version=0, score=0.0, payload={'a': [1, 2, 3, 4]}, vector=None, shard_key=None, order_value=None),
 ScoredPoint(id=2, version=0, score=0.0, payload={'a': [2, 3, 4, 5]}, vector=None, shard_key=None, order_value=None),
 ScoredPoint(id=1, version=0, score=0.0, payload={'a': [1, 2, 3, 4]}, vector=None, shard_key=None, order_value=None),
 ScoredPoint(id=2, version=0, score=0.0, payload={'a': [2, 3, 4, 5]}, vector=None, shard_key=None, order_value=None),
 ScoredPoint(id=1, version=0, score=0.0, payload={'a': [1, 2, 3, 4]}, vector=None, shard_key=None, order_value=None),
 ScoredPoint(id=2, version=0, score=0.0, payload={'a': [2, 3, 4, 5]}, vector=None, shard_key=None, order_value=None),
 ScoredPoint(id=2, version=0, score=0.0, payload={'a': [2, 3, 4, 5]}, vector=None, shard_key=None, order_value=None)]

However, we're not filling order_value in local client

@joein
Copy link
Copy Markdown
Member

joein commented Apr 24, 2025

I addressed it and added a test

@coszio coszio marked this pull request as ready for review April 24, 2025 13:31
@coszio
Copy link
Copy Markdown
Contributor Author

coszio commented Apr 24, 2025

✅ can't approve my own PR

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
tests/congruence_tests/test_scroll_order_by.py (1)

131-147: Good test case for deduplication with overlapping values

This test effectively validates the deduplication functionality by:

  1. Creating points with overlapping integer array values (2, 3, 4)
  2. Verifying consistent behavior across all client types (local, HTTP, gRPC)

Consider enhancing this test with additional edge cases:

 fixture_points = [
     models.PointStruct(id=1, vector=[], payload={"integer_array": [1, 2, 3, 4]}),
     models.PointStruct(id=2, vector=[], payload={"integer_array": [2, 3, 4, 5]}),
+    models.PointStruct(id=3, vector=[], payload={"integer_array": [3, 4, 5, 6]}),
+    models.PointStruct(id=4, vector=[], payload={"integer_array": []}),
+    models.PointStruct(id=5, vector=[], payload={"integer_array": [4, 4, 4]}),
 ]

This would test empty arrays and repeated values within the same array.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 19c43b9 and d80024e.

📒 Files selected for processing (2)
  • qdrant_client/local/local_collection.py (2 hunks)
  • tests/congruence_tests/test_scroll_order_by.py (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • qdrant_client/local/local_collection.py
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: Python 3.13.x on ubuntu-latest test
  • GitHub Check: Python 3.12.x on ubuntu-latest test
  • GitHub Check: Python 3.11.x on ubuntu-latest test
  • GitHub Check: Python 3.10.x on ubuntu-latest test
  • GitHub Check: Python 3.9.x on ubuntu-latest test
🔇 Additional comments (3)
tests/congruence_tests/test_scroll_order_by.py (3)

4-4: Good addition of the to_order_value import

This import is necessary for the new functionality that standardizes payload values for correct comparison, especially when handling array values.


41-55: Updated scroll logic correctly handles order_value and arrays

The changes appropriately refactor the scroll logic in two important ways:

  1. Using record.order_value instead of direct payload access, which aligns with the deduplication changes
  2. Adding proper handling for both scalar and list payload values, with consistent value conversion

The implementation correctly handles arrays by converting each item and checking if any matches the last seen value, which is essential for the deduplication feature to work properly.


96-98: Clean helper function addition

This helper function follows the same pattern as the existing ones, maintaining code consistency while supporting the new test case for integer arrays.

@joein joein merged commit 337c701 into dev Apr 24, 2025
14 checks passed
joein added a commit that referenced this pull request Apr 24, 2025
* dedup order_by by value and id

* fix: fill order_value when order_by is used

* tests: add tests for duplicated values, fix payload value comparison

---------

Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants