1

我正在使用响应式 MongoDb,并尝试基于权重实现自由文本搜索

implementation("io.micronaut.mongodb:micronaut-mongo-reactive")

在 POJO 下方

public class Product {
    @BsonProperty("_id")
    @BsonId
    private ObjectId id;
    private String name;
    private float price;
    private String description;
}

试过这个简单的例子

public Flowable<List<Product>> findByFreeText(String text) {
    LOG.info(String.format("Listener --> Listening value = %s", text));
    Flowable.fromPublisher(this.repository.getCollection("product", List.class)
            .find(new Document("$text", new Document("$search", text)
                    .append("$caseSensitive", false)
                    .append("$diacriticSensitive", false)))).subscribe(item -> {
                System.out.println(item);
            }, error -> {
                System.out.println(error);
            });
    return Flowable.just(List.of(new Product()));
}

我认为这不是实现自由文本搜索的正确方法。

4

1 回答 1

1

起初你不需要拥有Flowablewith ListProduct因为Flowable不像Single. 所以,拥有Flowable<Product>. 然后你可以简单地从方法返回Flowable实例。find

然后可以像这样实现文本搜索:

public Flowable<Product> findByFreeText(final String query) {
    return Flowable.fromPublisher(repository.getCollection("product", Product.class)
        .find(new Document("$text",
            new Document("$search", query)
                .append("$caseSensitive", false)
                .append("$diacriticSensitive", false)
        )));
}

然后由方法的使用者决定如何订阅结果Flowable。在控制器中,您可以直接返回Flowable实例。如果您需要在代码中的某个地方使用它,您可以这样做subscribe()等等blockingSubscribe()

您当然可以像这样通过 JUnit 对其进行测试:

@MicronautTest
class SomeServiceTest {
    @Inject
    SomeService service;

    @Test
    void findByFreeText() {
        service.findByFreeText("test")
            .test()
            .awaitCount(1)
            .assertNoErrors()
            .assertValue(p -> p.getName().contains("test"));
    }
}

更新:您可以通过在logback.xml中设置它来调试与 MongoDB 的通信(Micronaut 使用 Logback 作为默认日志记录框架)日志记录配置文件:

<configuration>
    ....
    <logger name="org.mongodb" level="debug"/>
</configuration>

然后你会在日志文件中看到:

16:20:21.257 [Thread-5] DEBUG org.mongodb.driver.protocol.command - Sending command '{"find": "product", "filter": {"$text": {"$search": "test", "$caseSensitive": false, "$diacriticSensitive": false}}, "batchSize": 2147483647, "$db": "some-database"}' with request id 6 to database some-database on connection [connectionId{localValue:3, serverValue:1634}] to server localhost:27017
16:20:21.258 [Thread-8] DEBUG org.mongodb.driver.protocol.command - 16:20:21.258 [Thread-7] DEBUG org.mongodb.driver.protocol.command - Execution of command with request id 6 completed successfully in 2.11 ms on connection [connectionId{localValue:3, serverValue:1634}] to server localhost:27017

然后,您可以从日志中复制命令并在 MongoDB CLI 中尝试,或者您可以安装MongoDB Compass,您可以在其中进行更多操作并查看命令是否正确。

于 2020-11-01T11:01:26.130 回答