Запросы MongoDB Panache не возвращают никакого результата

У меня проблемы с запросами в MongoDB. Всякий раз, когда я пытаюсь найти по идентификатору или любому другому полю, я всегда получаю ноль результатов. И у меня также возникают проблемы с использованием оператора "нравится".

Я хочу запросить названия книг без учета регистра. И я знаю, что в MongoDB это можно сделать так:

{title: {$regex: /^query.*/i}}

И я пытаюсь сделать это с помощью Panache, но не могу заставить его работать:

Book.find("title like ?1", "/^" + query + ".*/i");

Я вижу, что на консоли распечатывается следующая строка: {'title':{'$regex':'/^Harr.*/ I'}}

Я также пробовал это с помощью документа, но тоже безуспешно:

Document query = new Document();
query.put("title", "$regex: /^" + query + ".*/i");
Book.find(query);

И я получаю ноль результатов.

А вот и мой класс Book:

public class Book extends PanacheMongoEntity {

@NotEmpty
public String title;

@NotEmpty
public String isbn;

@NotEmpty
public String author;

@Min(1)
@NotNull
public BigDecimal price;
}

А вот и мой BookResource:

@Produces(APPLICATION_JSON)
@Consumes(APPLICATION_JSON)
@Path("/books")
public class BookResource {

@GET
public List<Book> get() {
    return Book.listAll();
}

@GET
@Path("/{id}")
public Book find(@PathParam("id") String id) {
    return (Book) Book.findByIdOptional(id).orElseThrow(() -> new NotFoundException("Book not found"));
}

@GET
@Path("/title/{title}")
public PanacheQuery<PanacheMongoEntityBase> findByTitle(@PathParam("title") String title) {
    Document query = new Document();
//        query.put("title", new BasicDBObject("$regex", ).append("$options", "i"));

    return Optional.ofNullable(Book.find("title like ?1", format("/^%s.*/i", title))).orElseThrow(() -> new NotFoundException("Book not found"));
}

@POST
public void add(@Valid Book book) {
    Book.persist(book);
}

@PUT
@Path("/{id}")
public void update(@PathParam("id") String id, @Valid Book book) {
    Book result = Book.findById(id);
    if (result != null) {
        result.author = book.author;
        result.isbn = book.isbn;
        result.price = book.price;
        result.title = book.title;

        Book.update(result);
    }
}
}

Когда я выполняю findAll через curl, я получаю следующее:

[
{
"id": "5eb9475b8a4314145246cc10",
"author": "J.K. Rowling",
"isbn": "12345678",
"price": 24.95,
"title": "Harry Potter 1"
},
{
"id": "5eb95a758a4314145246cc25",
"isbn": "456",
"price": 0,
"title": "Java for dummies"
},
{
"id": "5eb95b1a8a4314145246cc27",
"author": "steven king",
"isbn": "456",
"price": 10,
"title": "IT"
}
]

И когда я пытаюсь найти книгу по идентификатору, я также получаю нулевой результат:

curl -X GET "http://localhost:8080/books/5eb9475b8a4314145246cc10" -H "accept: application/json"

=> 404 No Books found.

Единственная операция, которая кажется работающей, - это POST (persist), остальные методы ничего не возвращают.

У меня следующая установка:

  • MongoDB 4.2 работает через Docker
  • Quarkus 1.4.2
  • JDK 11

А вот и мой application.properties:

quarkus.mongodb.connection-string=mongodb://localhost:27017
quarkus.mongodb.database=books
quarkus.log.category."io.quarkus.mongodb.panache.runtime".level=DEBUG

1 ответ

Следующий фрагмент кода неверен:

@GET
@Path("/title/{title}")
public PanacheQuery<PanacheMongoEntityBase> findByTitle(@PathParam("title") String title) {
    Document query = new Document();
    //query.put("title", new BasicDBObject("$regex", ).append("$options", "i"));

    return Optional.ofNullable(Book.find("title like ?1", format("/^%s.*/i", title))).orElseThrow(() -> new NotFoundException("Book not found"));
}

Book.find() вернуть PanacheQuery, вам нужно вызвать одну из операций терминатора запроса для получения результатов: list/stream/findFirst/findOne.

Я бы предложил реализовать это так:

@GET
@Path("/title/{title}")
public List<Book> findByTitle(@PathParam("title") String title) {
    return Book.list("title like ?1", format("/^%s.*/i", title)));
}

list() это ярлык для find().list(), если вам не нужна разбивка на страницы или другие вещи, доступные на PanacheQuery интерфейс, который вы можете использовать напрямую list().

Другие вопросы по тегам