2012-03-26 25 views
6

Tôi đã gắn thẻ các đối tượng trong một kho lưu trữ Jackrabbit (trên thực tế Adobe/ngày CQ của CRX, nhưng tôi nghĩ rằng đây là mã Jackrabbit):tìm kiếm Jackrabbit qua các nút tham gia

  • tài sản: tags = A, B
    • dữ liệu tài sản con 1: tags = A, C, E
    • dữ liệu tài sản con 2: tags = D, E

tôi muốn q uery chống lại sự kết hợp của tập hợp các thẻ và một đứa trẻ, nghĩa là "BC" sẽ khớp với nội dung vì chúng tôi có các phần tử trong cha mẹ và con 1, nhưng "CD" sẽ không khớp vì không có sự kết hợp của phụ huynh và một con khớp với điều đó vì C và D được phân tách trên các nút dữ liệu con riêng biệt.

Có cách nào để thực hiện việc này trong Jackrabbit không? Chúng tôi có thể viết một truy vấn XPath

\\element(*, dam:Asset)[(@tags = 'C' or *\@tags='C') 
         and (@tags = 'D' or *\@tags='D')] 

nhưng điều đó sẽ không làm việc vì XPath dường như không đảm bảo rằng các * gia nhập tài sản con đều giống nhau, ví dụ này có nghĩa là "bất kỳ đứa trẻ có C/D" và như vậy sẽ phù hợp với tài sản của tôi, vì 1+ trẻ em có một C và 1+ trẻ em có một D. thay vào đó tôi có thể sử dụng JCR-SQL2

SELECT * FROM dam:Asset as asset 
    LEFT OUTER JOIN nt:unstructured as child ON ISCHILDNODE(child,asset) 
    WHERE (asset.tags = 'C' or child.tags = 'C') 
    AND (asset.tags = 'D' or child.tags = 'D') 

nhưng không có SELECT DISTINCT trong JCR-SQL2: nếu thay vào đó tôi tìm kiếm cho "BE" Tôi sẽ nhận lại nội dung này hai lần bởi vì điều này khớp với cả nội dung + child1 và nội dung + child2.

Tôi có thể xử lý kết quả truy vấn trong Java, tức là lọc ra kết quả trùng khớp giả cho trường hợp thứ nhất hoặc lọc kết quả trùng lặp cho trường hợp thứ hai, nhưng tôi lo lắng điều này sẽ ảnh hưởng như thế nào đến hiệu suất phân trang: để quét nhiều nút hơn mức cần thiết để loại bỏ các nút không hợp lệ và tôi cần quét rất nhiều để tính toán kích thước kết quả chính xác cho phân trang. Điều này nên rẻ hơn đối với trường hợp SQL2 thứ hai vì nếu tìm kiếm của tôi được đặt hàng, tôi có thể phát hiện các bản sao dựa trên đường dẫn nút và tất cả các bản sao sẽ liên tiếp, vì vậy tôi có thể tìm thấy giá trị của dữ liệu với giá rẻ nhất định. toàn bộ nút cho mỗi kết quả, nhưng tôi không biết chi phí quét tất cả các kết quả cho số phân trang quá ngay cả đối với trường hợp chỉ đường dẫn đơn giản.

Một tùy chọn khác mà chúng tôi đã xem xét là làm biến đổi các thẻ thành một nút duy nhất. Trong trường hợp này, để giữ cho tìm kiếm chính xác, điều đó sẽ có nghĩa là tạo một thuộc tính combined_tags mới trong mỗi nút con và thực hiện tất cả các tìm kiếm đối với tập hợp các nút con. Tuy nhiên, điều này vẫn gặp vấn đề riêng biệt, chúng ta nên kết hợp hai nút con bên dưới cùng một nội dung.

Cảm ơn mọi đề xuất. Đây là một ví dụ lớn đã và sẽ cần phải mở rộng hơn nữa. Tôi đã nhìn thấy các câu hỏi khác mà nói ModeShape là một thực hiện JCR mà có SELECT DISTINCT nhưng tôi nghĩ rằng chuyển sang ModeShape chỉ cho rằng sẽ phải là phương sách cuối cùng, nếu thực sự nó có thể lưu trữ CQ trên ModeShape.


Một ý tưởng chúng tôi đã đưa ra hiện nay là tính mỗi công đoàn của các thẻ tài sản và các thẻ con và kết hợp các thẻ vào một chuỗi duy nhất sau đó viết mỗi giá trị như một thuộc tính đa trị của tài sản, ví dụ:asset + child1 = "A B C E" và nội dung + child2 = "A B D E", vì vậy chúng tôi nhận được

  • asset: tags = A, B; tagUnions = "ABCE", "ABDE"

Chừng nào chúng ta định nghĩa một trật tự cố định để kết hợp thẻ vào một chuỗi (ví dụ như chữ cái) chúng ta có thể tìm kiếm bất kỳ sự kết hợp sử dụng tagUnions LIKE '%B%C%' (trừ tôi muốn sử dụng delimiters thích giữa các thẻ trong trường hợp thực). Trong khi điều này sẽ làm việc xa như chúng ta có thể thấy tôi không thực sự thích nó: có nhiều thẻ có khả năng trên mỗi nội dung + con, tất cả có tên dài hơn các chữ cái duy nhất nghĩa là chúng tôi sẽ kết thúc bằng chuỗi dài thực hiện các truy vấn LIKE trên tất cả trong số đó có khả năng không thể được lập chỉ mục một cách hiệu quả.

Một bước nữa là tạo một bitmap: xác định A = 1, B = 2 vv và do đó lưu trữ một mảng số nguyên nhiều giá trị ở đây sau đó thực hiện so sánh bitwise. Tuy nhiên đó là khả năng giới hạn 64 thẻ khác nhau và kể từ khi chúng tôi có 1.000+ Tôi không nghĩ rằng chúng tôi có thể làm điều này - ngay cả khi JCR hỗ trợ hoạt động bitwise, mà tôi mong đợi nó sẽ không.

Vì vậy, tôi vẫn đang tìm kiếm giải pháp giống như cơ sở dữ liệu sạch cho việc này. Bạn đã bỏ lỡ tiền thưởng mà tôi đã đưa ra nhưng vẫn còn ve, phiếu và lòng biết ơn đối với bất kỳ sự giúp đỡ nào.

Trả lời

1

Từ the Apache Jackrabbit mailing list:

Vâng, không may các truy vấn liên minh không được hỗ trợ. Bất kỳ công việc nào trên khu vực sẽ được đánh giá cao.

Trong khi giải pháp tốt nhất có thể là thực hiện hai truy vấn riêng biệt và để thực hiện rõ ràng công đoàn trong mã ứng dụng bằng cách kết hợp hai tập hợp kết quả.

Vì vậy, đó là một tùy chọn. Nhìn vào SQL bạn đã cung cấp:

nhưng không có SELECT DISTINCT trong JCR-SQL2: nếu thay vào đó tôi tìm kiếm cho "B E" Tôi sẽ nhận được tài sản này trở lại hai lần vì này phù hợp với cả hai tài sản + child1 và nội dung + child2.

Tôi đã xem xét các giải pháp có thể được hỗ trợ bởi Jackrabbit và đưa ra tay trống. Tuy nhiên, tôi đồng ý với những giải pháp được trình bày here:

Những gì tôi đã làm là để làm một SELECT đơn giản với BYs TRÌNH TỰ chiếm đoạt ... sau đó mỗi lần tôi sử dụng liên tiếp, tôi veried rằng nó không phải là như nhau như :-) trước

(SICS bảo tồn.)

trong khi ORDER BY là có khả năng không rõ ràng, trừ khi bạn yêu cầu cơ sở dữ liệu được hỗ trợ sắp xếp, là có bất cứ điều gì ngăn cản bạn từ việc xây dựng một HashSet trong điều khiển của bạn để hạn chế kết quả của bạn chỉ giá trị duy nhất bằng cách sử dụng API JCR?

+0

Cảm ơn. Nó không thực sự là một SQL 'UNION' tôi cần về một liên minh thiết lập qua hai truy vấn nhưng tôi tính toán một trận đấu dựa trên một liên kết hợp lý của hai thuộc tính trên các nút khác nhau, vì vậy nó là một câu lệnh SQL' JOIN' và 'SELECT DISTINCT' Tôi cần.Giải pháp bạn liên kết - sắp xếp theo thứ tự và xóa các bản sao liên tiếp - là một trong những ý tưởng tôi đã đề cập trong đoạn về kết quả sau xử lý và vấn đề với điều đó là phân trang đúng: Tôi cần quét tất cả các bản ghi đến hiện tại trang để tìm ra nơi trang thực sự bắt đầu và quét mọi thứ để có được tổng số trang chính xác. – Rup

+0

... và hệ thống tôi đang làm việc với hàng triệu tài sản, vì vậy 10.000 kết quả từ truy vấn đơn giản không phải là chưa từng thấy - tôi không thể giả sử tôi có một số lượng nhỏ kết quả như anh ta nói giải pháp được liên kết đó. Tôi yêu cầu phân loại dựa trên cơ sở dữ liệu để có được phân trang hiệu quả tôi nghĩ. Trong mọi trường hợp, tài liệu Jackrabbit khuyên bạn nên sử dụng 'ORDER BY' ngay từ khi thứ tự mặc định JCR (trừ khi bị vô hiệu hóa trong repository.xml) có khả năng đắt tiền để tính toán. – Rup

+0

@Rup Cảm ơn bạn đã cập nhật. Như bạn đề cập, việc xử lý sau kết quả trong Java là có thể, nhưng có thể tốn kém khi bạn duyệt qua các nút bổ sung mà bạn đã truy cập. Vì vậy, điều này dẫn đến câu hỏi về việc truyền tải hiệu quả thông qua cấu trúc dữ liệu của bạn. Hmn. Tôi sẽ phải xem xét điều này sau và lấy lại cho bạn. :) – MrGomez